【POJ】3320--Jessica's Reading Problem(尺取法)

来源:互联网 发布:java保存用户密码加密 编辑:程序博客网 时间:2024/05/16 18:59
Jessica's Reading Problem
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 13776 Accepted: 4728

Description

Jessica's a very lovely girl wooed by lots of boys. Recently she has a problem. The final exam is coming, yet she has spent little time on it. If she wants to pass it, she has to master all ideas included in a very thick text book. The author of that text book, like other authors, is extremely fussy about the ideas, thus some ideas are covered more than once. Jessica think if she managed to read each idea at least once, she can pass the exam. She decides to read only one contiguous part of the book which contains all ideas covered by the entire book. And of course, the sub-book should be as thin as possible.

A very hard-working boy had manually indexed for her each page of Jessica's text-book with what idea each page is about and thus made a big progress for his courtship. Here you come in to save your skin: given the index, help Jessica decide which contiguous part she should read. For convenience, each idea has been coded with an ID, which is a non-negative integer.

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.

Sample Input

51 8 8 8 1

Sample Output

2

Source

POJ Monthly--2007.08.05, Jerry

[Submit]   [Go Back]   [Status]   [Discuss]




思路分析:(1)题意:每一页都只有一个知识点,知识点都有编号,用数字表示,一个知识点可能在多页都有出现,求最少的页数包含全部的知识点。(2)分析:用尺取法,从起点到终点,起点和终点的初始值都为0。先固定一个起点,终点依次加1,统计区间中不同知识点的个数。如果到最后P点,知识点个数还是小于n,那么就可以结束循环了,因为以后再也不会有了。知识点个数大于等于n,就可以以先结束循环,并更新区间长度。如果当前区间起点处的知识点出现的次数为1,即只在起点处出现一次,在后面到区间终点没有出现过,在更新起点(加1)时,知识点数目要减1,因为在暂时区间不存在这个知识点。用STL中的set统计不同知识点的个数,map<int,int>表示某一个知识点出现的个数。



代码如下:

#include<cstdio>#include<cstring>#include<map>#include<set>#include<algorithm>using namespace std;#define MAX 1000000int n,P;int a[MAX+11];void solve(){int st,ed,num;st=ed=num=0;int ans=P;map<int,int> cos;//第一个参数为知识点,第二个参数为知识点出现的个数 for(;;){while(ed<P&&num<n){if(cos[a[ed++]]++==0)//表示当前终点对应的知识点已经出现了0次, 那么终点加1,此知识点出现的个数加1 num++;//表示出现不同知识点的个数 }if(num<n)//只要num<n,那么以后再也不可能出现num>=n,直接结束循环即可 break;ans=min(ans,ed-st);//更新ans if(--cos[a[st++]]==0)//当前区间起点的知识点只出现一次,说明从起点的下一点到当前终点之间没有出现过 ,那么减1,进入新的区间 num--;}printf("%d\n",ans);}int main(){while(~scanf("%d",&P)){set<int> cnt;//表示统计不同知识点的个数 for(int i=0;i<P;i++){scanf("%d",&a[i]);cnt.insert(a[i]); }n=cnt.size() ;//表示有多少个不同的知识点 solve();}return 0;}




阅读全文
0 0
原创粉丝点击