POJ 3320 尺取
- 题目的意思是:每个数代表一个知识点,然后按顺序给出知识点的序列,求涵盖了所有知识点的最短连续子序列。
- 知识点的范围: 1<p<1e6
- 每个数可以看作带符号的32位数
代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string.h>
#include<set>
#include<map>
using namespace std;
const int maxp=1e6+50;
int a[maxp];
set<int>s;
map<int,int>m;
int n,i,j,ans,p,maxn,sum;
int main(){
cin>>p;
ans=p+1;
for(int k=0;k<p;k++){
scanf("%d",&a[k]);
s.insert(a[k]);
}
maxn=s.size();
while(1){
while(j<p&&sum<maxn){
if(m[a[j]]==0){
sum++;
}
m[a[j]]++;
j++;
}
if(sum<maxn||j>p)break;
while(m[a[i]]>1){
m[a[i++]]--;
}
ans=min(ans,j-i);
sum--;
m[a[i++]]--;
}
cout<<ans<<endl;
}
- PS:刚开始没用map,用的一个int数组来标记的子序列中数的个数,结果一直RE,没注意每个知识点代表的数的范围是20-231,int数组就超了呗