UVA:11536 Smallest Sub-Array(尺取法)

来源:互联网 发布:淘宝海昌隐形眼镜 编辑:程序博客网 时间:2024/05/21 23:32

题意:求包含数字1——K的最小区间长度。

思路:尺取法。维护一个区间,右端点扩张一直到区间满足条件,此时更新答案,然后左端点逐步左移。

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <map>#include <vector>#include <stack>#include <unordered_map>#include <queue>using namespace std;const int maxn=1000005;int a[maxn];int solve(const vector<int> &v,int k){    int ans=v.size()+1,st=0,ed=0;    unordered_map<int,int> pos;    int sz=0;    while(true)    {        while(ed<v.size()&&sz<k)        {            if(1<=v[ed]&&v[ed]<=k)            {                if(pos.find(v[ed])==pos.end()||pos[v[ed]]<st) ++sz;                pos[v[ed]]=ed;            }            ++ed;        }        if(sz<k) break;        ans=min(ans,ed-st);        if(1<=v[st]&&v[st]<=k)        {            if(pos[v[st]]==st)                --sz;        }        ++st;    }    return ans;}int main(){    int T,kase=0;    scanf("%d",&T);    a[1]=1,a[2]=2,a[3]=3;    while(T--)    {        int N,M,K;        scanf("%d%d%d",&N,&M,&K);        for(int i=4; i<=N; ++i)            a[i]=(a[i-1]+a[i-2]+a[i-3])%M+1;        vector<int> v(a+1,a+N+1);        int ans=solve(v,K);        printf("Case %d: ",++kase);        if(ans==v.size()+1) puts("sequence nai");        else printf("%d\n",ans);    }    return 0;}


0 0