您的位置:首页 > 其它

poj 3320 Jessica's Reading Problem

2014-03-20 19:54 260 查看
跟poj 3061一样,都是取尺法的应用。

题目大意:

XXX要准备考试,书总共有P页,第i页恰好有一个知识点ai,书中的同一个知识点可能会被多次提到,所以他希望看其中连续的一些页的书来把所有的知识点都给看完。。

其实页数可以看作连续的序列,然后就是要求出一个子序列,子序列的要求的包涵所有知识点都有的页数,且子序列的长度要最短。

首先我们并不知道总共有多少个知识点,这是个先要记录的。

不断的把序列中的元素加入到子序列中,知识点的数目会不断的增加,当知识点是数目满了之后,把子序列前面的元素开始剔除,再看看现在的子序列还是否满足这个条件。满足继续删除子序列前面的元素,否则的话把后面的元素加入到子序列中。

注意中间过程知识点数的增加或减少的维护。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<algorithm>
#include<set>
#include<map>
using namespace std;
const int INF = 0x3f3f3f3f;
const int vMax = 100010;
int P[vMax];
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif // LOCAL
int n;
while(scanf("%d",&n) != EOF)
{
memset(P,0,sizeof(P));
set<int>all;
for(int i = 1; i <= n ; i++)
{
scanf("%d",&P[i]);
all.insert(P[i]);//set记录所有的知识点
}
map<int,int>cnt;
int sta = 1,fin = 0;
int t = 0 ;
int res = n;
while(1)
{
while(t < all.size() && fin <= n)
{
if(cnt[P[++fin]] ++ == 0)
{
t++;//新知识点
}
}
if(t < all.size())
{
break;
}
res = min(res,fin - sta+1);
if(--cnt[P[sta++]] == 0)//知识点数目减少
{
t--;
}
}
printf("%d\n",res);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: