题意
给n和m
个数为n的数组,内容是1~m之间的数字,求最小的包含1~m(至少出现过一次)l,r(如果有相同的区间长度,l要最小)
思路
先第一步,找到右边 r(至少出现过一次)的值,然后将l从1 开始到r,无用的重复的删除,初次确认L=l,R=r
(因为没有想到第二步一直只有45分)
第二步,在 r 右移动,判断 vis[a[l]] 的值是否大于1,大于一就减,l右移
举个例子
6 3
1 2 2 3 2 1
如果没有第二步骤答案就是1 4
正确答案就是4 6
#include<bits/stdc++.h> using namespace std; #define ll long long #define il inline #define it register int #define inf 0x3f3f3f3f #define lowbit(x) (x)&(-x) #define mem(a,b) memset(a,b,sizeof(a)) #define mod 998244353 const int maxn=1e6+10; int n,k; int a[maxn],vis[2100]={0}; int main() { scanf("%d%d",&n,&k); for(it i=1;i<=n;i++){ scanf("%d",&a[i]); } int sum=0,l,r,zl,zr; for(it i=1;i<=n;i++){ if(vis[a[i]]==0){sum++;}vis[a[i]]++; if(sum==k){r=i;break;} } for(it i=1;i<=r;i++){ vis[a[i]]--;if(vis[a[i]]==0){vis[a[i]]++;l=i;break;} } zl=l,zr=r; for(it i=r+1;i<=n;i++){ vis[a[i]]++;r++; while(vis[a[l]]>1){ vis[a[l++]]--; } if(r-l<zr-zl){ zr=r;zl=l; } } printf("%d %d ",zl,zr); return 0; }