题目描述

博览馆正在展出由世上最佳的 M 位画家所画的图画。

wangjy想到博览馆去看这几位大师的作品。

可是,那里的博览馆有一个很奇怪的规定,就是在购买门票时必须说明两个数字,

a和b,代表他要看展览中的第 a 幅至第 b 幅画(包含 a 和 b)之间的所有图画,而门票

的价钱就是一张图画一元。

为了看到更多名师的画,wangjy希望入场后可以看到所有名师的图画(至少各一张)。

可是他又想节省金钱。。。

作为wangjy的朋友,他请你写一个程序决定他购买门票时的 a 值和 b 值。

输入输出格式

输入格式:

第一行是 N 和 M,分别代表博览馆内的图画总数及这些图画是由多少位名师的画

所绘画的。

其后的一行包含 N 个数字,它们都介于 1 和 M 之间,代表该位名师的编号。

输出格式:

a和 b(a<=b) 由一个空格符所隔开。

保证有解,如果多解,输出a最小的。

输入输出样例

输入样例#1:

12 5
2 5 3 1 3 2 4 1 1 5 4 3
输出样例#1:

2 7

说明

约定 30%的数据N<=200 , M<=20

60%的数据N<=10000 , M<=1000

100%的数据N<=1000000 , M<=2000

Sol

本题是二分答案,如何判断出来的呢?满足二分单调性!

二分单调性如何理解?对于一段区间,如果它能满足看遍所有的画,那么比它小的区间不一定能看遍所有的画,而比它大的区间一定能看遍所有的画。

二分的复杂度是logn,由于本题数据达到了1e6,所以二分答案判断的函数check复杂度必须满足在O(n)以内。

此时我们也确定了二分的对象是区间长度。

LVYOUYW学长这样解释:“首先考虑如果给定拥有钱的数量,那么我们可以在O(n)的时间内枚举所有的情况,于是我们可以二分答案,二分拥有钱的数量,然后去判断是否可行。”’

由于约束check函数在O(n)内,我们不可能枚举左端点,并每次遍历整个区间,那样可能会达到O(n²)。

于是我们可以在每次check时,先从1号端点出发,处理出从1出发这段区间中,看到的不同画的个数,并用一个数组cnt维护每张画出现了多少张。

此后就像滑动窗口一样啦!

code

 #include<cstdio>
#include<algorithm>
#include<cstring> using namespace std; int n,m,ansl,ansr;
int a[],cnt[]; bool check(int x)
{
int tmp=;
memset(cnt,,sizeof(cnt));
for(int i=;i<=x;i++)
{
if(!cnt[a[i]]) tmp++;
cnt[a[i]]++;
}
if(tmp==m)
{
ansl=,ansr=x;
return ;
}
int nowl=,nowr=+x-;
for(int i=nowl;nowr<=n;nowl++,nowr++)
{
cnt[a[nowl-]]--;
if(!cnt[a[nowl-]]) tmp--;
cnt[a[nowr]]++;
if(cnt[a[nowr]]==) tmp++;
if(tmp==m)
{
ansl=nowl,ansr=nowr;
return ;
}
}
return ;
} int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) scanf("%d",&a[i]);
ansl=,ansr=n;
int l=,r=n;
while(l<r)
{
int mid=(l+r)>>;
if(check(mid)) r=mid;
else l=mid+;
}
printf("%d %d",ansl,ansr);
return ;
}

Summary

思考这道题的时候被学长“质问”有没有什么想法,其实当时在纠结而二分的对象是什么。学长箴言:二分是一种优化的枚举,只要满足二分单调性,基本都可用二分求解。

另外,代码实现的时候竟然有一个WA掉的点会输出0 0,还是赋一下ansl,ansr的初值比较好!

最新文章

  1. 关于GreenOdoo的一个Bug
  2. DataGridView很详细的用法(转载)
  3. 以Self Host的方式来寄宿Web API
  4. 简单的分页存储过程,Json格式日期转换为一般日期
  5. WP8__从windowsphone app store 中根据app id获取应用的相关信息(下载网址及图片id等)
  6. Apache OFBiz 学习笔记 之 实体引擎
  7. Maven 添加Jetty
  8. Unicode字段也有collation
  9. C# 正则表达式 结合 委托
  10. 201521123110《Java程序设计》第10周学习总结
  11. codeforces 893C Rumor 前向星+dfs
  12. Web服务器Tomcat集群与负载均衡技术
  13. 使用jenkins自部署Coding项目
  14. openwrt页面显示问题修改
  15. vs visual stdio 调试 显示指针为数组
  16. Ubuntu 利用 crontab 和 notify-send 定时发送桌面通知,提示该休息啦
  17. 【Spring Boot &amp;&amp; Spring Cloud系列】那些Spring Boot中踩过的坑
  18. 微信小程序 - 简述
  19. 【C#小知识】C#中一些易混淆概念总结(二)--------构造函数,this关键字,部分类,枚举 分类: C# 2014-02-03 01:24 1576人阅读 评论(0) 收藏
  20. python基础-实现进度条功能,for和yield实现

热门文章

  1. 我的Android Studio 优化之路
  2. Python访问MySQL数据库并实现其增删改查功能
  3. VM虚拟机ping不通局域网其他主机的解决办法
  4. hdu 1879 继续畅通project
  5. 【Mongodb教程 第一课 补加课1 】windows7 下安装mongodb 开启关闭服务
  6. jquery 动态绑定bind()及模拟鼠标点击A链接
  7. CSS的两个class选择器紧挨在一起
  8. springMVC中的中心控制Servlet是那个类?(B)
  9. ABAP Debug 技巧
  10. HttpServlet容器响应Web客户流程