逛画展
题目描述
博览馆正在展出由世上最佳的 M 位画家所画的图画。
wangjy想到博览馆去看这几位大师的作品。
可是,那里的博览馆有一个很奇怪的规定,就是在购买门票时必须说明两个数字,
a和b,代表他要看展览中的第 a 幅至第 b 幅画(包含 a 和 b)之间的所有图画,而门票
的价钱就是一张图画一元。
为了看到更多名师的画,wangjy希望入场后可以看到所有名师的图画(至少各一张)。
可是他又想节省金钱。。。
作为wangjy的朋友,他请你写一个程序决定他购买门票时的 a 值和 b 值。
输入格式
第一行是 N 和 M,分别代表博览馆内的图画总数及这些图画是由多少位名师的画
所绘画的。
其后的一行包含 N 个数字,它们都介于 1 和 M 之间,代表该位名师的编号。
输出格式
a和 b(a<=b) 由一个空格符所隔开。
保证有解,如果多解,输出a最小的。
双指针法求最小区间包含m个不同元素;
sum记录区间的不同元素个数,当sum==m时,l 往右移(如果 l 位置上的元素个数大于等于2),更新最小区间就行,sum值都可以不变了;
代码:
#include<bits/stdc++.h>
#define LL long long
#define pa pair<int,int>
#define ls k<<1
#define rs k<<1|1
#define inf 0x3f3f3f3f
using namespace std;
const int N=1000100;
const int M=2000000;
const LL mod=1e9+7;
int n,m,a[N],vis[2100];
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
int sum=0,l=1,ans=2e9,L=1,R=n;
for(int r=1;r<=n;r++){
if(!vis[a[r]]) sum++;
vis[a[r]]++;
if(sum==m){
while(l<=r){
if(vis[a[l]]>=2) vis[a[l]]--,l++;
else break;
}
if(ans>r-l+1){
ans=r-l+1;
L=l,R=r;
}
}
}
cout<<L<<" "<<R<<endl;
return 0;
}