https://scut.online/p/243
这道题唯一难点在于如何快速确定m合法。可以统计滑动窗口中已有元素的数量。
#include<bits/stdc++.h> using namespace std; #define ll long long int n; int a[100005]; int suma[100005]; int sum; int cnta[100005]; int cntsum; bool ok(int m){ memset(cnta,0,sizeof(cnta)); cntsum=0; for(int i=0;i<m;i++){ if(cnta[a[i]]==0){ cntsum++; } cnta[a[i]]++; } if(cntsum==sum){ //m ok return 1; } for(int i=m;i<n;i++){ { cnta[a[i-m]]--; if(cnta[a[i-m]]==0) cntsum--; if(cnta[a[i]]==0) cntsum++; cnta[a[i]]++; } if(cntsum==sum){ //m ok return 1; } } return 0; } int main(){ while(~scanf("%d",&n)){ sum=0; memset(suma,0,sizeof(suma)); for(int i=0;i<n;i++){ scanf("%d",&a[i]); if(suma[a[i]]==0){ sum++; } suma[a[i]]++; } //printf("sum=%d ",sum); int l=1,r=n,m; int res=0; while(l<=r){ m=(l+r)/2; //cout<<m<<endl; if(m==l){ if(ok(m)){ res=l; } else{ res=r; } break; } if(ok(m)) r=m; else l=m+1; } printf("%d ",res); } }