Uva12174 Shuffle(滑动窗口)

  $play[i]$表示以$i$这个点结束的连续$s$个播放记录是否是无重复的,这样最后只需要枚举可能的播放时间,然后检查对应的播放区间是否是单独的就可以了。特殊情况是,出现的所有播放记录无重复,且长度小于等于$s$,这种情况,答案就是$s$。

AC代码

#include <stdio.h>
#include <string.h>
const int maxn = 100000 + 5;
int play[maxn], re[maxn], cnt[maxn];

int main() {
    int n, s, T;
    scanf("%d", &T);
    while(T--) {
        scanf("%d%d", &s, &n);
        memset(play, 0, sizeof(play));
        memset(cnt, 0, sizeof(cnt));
        for(int i = 0; i < n; i++) scanf("%d", &re[i]);
        int i = 0, j = 0;
        int only = 0;
        while(j < n) {
            cnt[re[j]]++;
            if(cnt[re[j]] == 1) only++;
            else only--;
            while(only != j-i+1) {
                cnt[re[i]]--;
                if(cnt[re[i]] == 1) only++;
                else only--;
                i++;
            }
            if(only == s || (j < s && only == j+1)) play[j] = 1;
            j++;
        }
        j--;
        int lim = j - i + 1;
        int ans = 0;
        if(lim == n) {
            ans = s;
        } else {
            for(int x = 1; x <= lim; x++) {
                int y = n - 1 - x;
                int flag = 1;
                while(y >= 0) {
                    if(!play[y]) {
                        flag = 0;
                        break;
                    }
                    y -= s;
                }
                if(flag) ans++;
            }
        }
        printf("%d
", ans);
    }
    return 0;
}

如有不当之处欢迎指出!

原文地址:https://www.cnblogs.com/flyawayl/p/8987301.html