P1638 逛画展
首先介绍尺取(双指针)
用于求解满足条件的最小区间问题
首先,从数组最左边元素开始,向右延伸r,使得最初满足条件。此时对于l为1来说,是最小的满足条件区间
接下来,开始将l变为2。变为2后,需要将r延长到能够满足条件的下一个r(可能不用延长,也可以先延长再把l变成2)。这样就得到了l为2时的最小区间(因为r不可缩小了)
以此类推,不断重复以上流程,直到l变为某个值后,再也找不到合适的r使得区间满足条件了。那么从左边界为1到此时的l-1为止中,所记录的区间大小最小的那一个就是我们所求的了,并没有遗漏任何可能的区间。
本题采用此思路即可求解,写得麻烦了些,不足为参考,看上面的思路就行啦
#include<iostream>
using namespace std;
int a[2005];
int painting[1000005];
int retire=0;
int l=1,r=1;
int n,m;
void initial(){
a[painting[r]]++;
retire++;
while(retire!=m){
r++;
if(a[painting[r]]==0)
retire++;
a[painting[r]]++;
}
}
int main(){
int need;
int ansl,ansr;
cin>>n>>m;
int min=n+5;
for(int i=1;i<=n;i++){
cin>>painting[i];
}
initial();
while(l<=r&&r<=n){
while(a[painting[l]]>1){
a[painting[l]]--;
l++;
}
need=painting[l];
if(r-l+1<min){
min=r-l+1;
ansl=l;
ansr=r;
}
while(painting[r+1]!=need&&r+1<=n){
r++;
a[painting[r]]++;
}
l++;
r++;
}
cout<<ansl<<' '<<ansr;
return 0;
}

浙公网安备 33010602011771号