您的位置:首页 > 其它

POJ_3320_Jessica's Reading Problem_尺取法

2014-10-27 23:04 204 查看
戴隐形看电脑好难受


题意:

女神Jessica要考试,学霸备胎给她总结了一下规律:书中每一页包含一些知识点,不同页上的知识点可能一样,Jessica需要看完所有的知识点,她想看一些连续的书页,然后包含所有书上的知识点,最少要读多少页?

Input

The first line of input is an integer P (1 ≤ P ≤ 1000000), which is the number of pages of Jessica's text-book. The second line contains
P non-negative integers describing what idea each page is about. The first integer is what the first page is about, the second integer is what the second page is about, and so on. You may assume all integers that appear can fit well in the signed 32-bit
integer type.

Output

Output one line: the number of pages of the shortest contiguous part of the book which contains all ideals covered in the book.

并不难的题,但是很少做尺取法这样机智的方法,没必要遍历所有情况,区间向后推进时会保留性质,所以可以将O(N^2)生生转化为O(N)。这种机智的方法我总是难以想到,就像一开始我不相信有看毛片算法这种可以把匹配整到O(M+N)的算法一样。

尺取法见《挑战程序设计竞赛》3.2

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<algorithm>
using namespace std;
#define mxn 1000010
#define inf 0x3f3f3f3f
int p;
int a[mxn];
map<int,int> m;
int main(){
while(scanf("%d",&p)!=EOF){
m.clear();
int cnt=0;
for(int i=0;i<p;++i){
scanf("%d",&a[i]);
if(m.find(a[i])==m.end()){
++cnt;
m.insert(pair<int,int>(a[i],0));
}
}
int ans=inf;
m.clear();
int l=0,r=0;
m.insert(pair<int,int>(a[l],1));
while(true){
while(r+1<p&&m.size()!=cnt){
if(m.find(a[++r])==m.end())
m[a[r]]=1;
else	++m[a[r]];
}
if(m.size()!=cnt)	break;
ans=min(ans,r-l+1);
--m[a[l]];
if(m[a[l]]==0)	m.erase(a[l]);
++l;
}
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: