P1638 逛画展

发布时间 2024-01-11 23:51:56作者: OKM_IS
首先介绍尺取(双指针)
用于求解满足条件的最小区间问题
首先,从数组最左边元素开始,向右延伸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;
}