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

题目:

思路:

读完题之后第一时间想到的是尺取法来做这个题,结果让自己写写崩了,还是练得少!!

到网上搜了一下学习了大佬的标记方法,用一个变量来判断是不是都已经出现,要比每次都判断一下快超多。

代码:

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define MAX 1e3
#define FRE() freopen("in.txt","r",stdin)
#define FRO() freopen("out.txt","w",stdout)
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
const int maxn = 1000100;
int a[maxn],vis[maxn];
int n,m,k;

void init(){
    memset(vis,0,sizeof(vis));
    a[1] = 1,a[2] = 2,a[3] = 3;
    for(int i=4; i<=n; i++){
        a[i] = (a[i-1]+a[i-2]+a[i-3])%m+1;
    }
}

int main(){
   // FRE();
    int kase=0,T;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d%d",&n,&m,&k);
        init();
        if(k > m || k>n){
            printf("Case %d: sequence nai\n",++kase);
            continue;
        }
        int ans = 100000000;
        int st=1,en=1,tot=0;
        while(en <= n){
            int t = a[en++];
            vis[t]++;
            if(t<=k && vis[t]==1) tot++;//标记区间个数get!!

            while(st<en && tot==k){
                ans = min(ans, en-st);
                t = a[st++];
                vis[t]--;
                if(t<=k && vis[t]==0) tot--;//标记区间个数
            }
            //cout<<"en: "<<en<<"  st:  "<<st<<endl;
        }
        if(ans>n){
            printf("Case %d: sequence nai\n",++kase);
        }else{
            printf("Case %d: %d\n",++kase,ans);
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/sykline/p/10350743.html