UVA-11536 Smallest Sub-Array
题目大意:给出一个有n个数的序列,找出最短的涵盖1~k之间所有整数的连续区间。
题目分析:扫描一遍序列,维护head、tail两个位置。要注意,最短的区间上两端的数一定[1,k]上。
代码如下:
# include<iostream> # include<cstdio> # include<cstring> # include<algorithm> using namespace std; const int INF=1<<30; int n,m,k,a[1000005],mark[1005]; bool ok() { for(int i=1;i<=k;++i) if(!mark[i]) return false; return true; } int solve() { if(k<=3) return k; memset(mark,0,sizeof(mark)); int head=0,tail,ans=INF; a[0]=1,a[1]=2,a[2]=3; mark[1]=mark[2]=mark[3]=1; for(tail=3;tail<n;++tail){ a[tail]=(a[tail-1]+a[tail-2]+a[tail-3])%m+1; ++mark[a[tail]]; while(head<=tail&&(a[head]<1||a[head]>k||mark[a[head]]>1)) --mark[a[head++]]; if(tail-head+1>=k&&tail-head+1<ans&&ok()) ans=tail-head+1; } return ans; } int main() { int T,cas=0; scanf("%d",&T); while(T--) { scanf("%d%d%d",&n,&m,&k); printf("Case %d: ",++cas); if(n<k||k>m){ printf("sequence nai\n"); continue; } int ans=solve(); if(ans==INF) printf("sequence nai\n"); else printf("%d\n",ans); } return 0; }