UVa #12174 Shuffle (例题8-15)

86 篇文章 0 订阅

连续子序列。。又是滑动窗口哈


这道题用滑动窗口做的话,无非就是枚举第一个窗口的起始位置,从 -s+1 到 0。(用负数表示开头的不完整周期) 然后判断每个窗口是不是都符合没有重复数字的要求


这道题和之前的滑动窗口不太一样,这道题要简单些:窗口的大小是固定的。我们只需要把每个元素的前一个出现位置记下来,在滑动窗口进行判断的时候,挨个看每个元素的上一次/下一次出现位置有没有在窗口范围内就可以了


可是其实解一共只有s种可能,滑动窗口做的只不过是在不断的排除可能性。如果不是为了练习滑动窗口,我们可以用一个更简单的方法:对于每个位置上的元素 a,找到它下次出现的位置 b,如果它俩距离小于 s ,则将右端贴着 b 的滑窗一直到左端贴着 a 的滑窗全部排除,因为这些滑窗都会造成元素的重复出现。


这样只需要从左到右扫描一次即可,复杂度O(n)


Run Time: 0.768s

#define UVa  "LT8-15.12174.cpp"
char fileIn[30] = UVa, fileOut[30] = UVa;

#include<cstring>
#include<cstdio>
#include<algorithm>

using namespace std;

//Global Variables. Reset upon Each Case!
const int maxn = 100000 + 10;
int s, n, x[maxn], vis[maxn];
int dist_to_next[maxn];
/

int main() {
    int T;
    scanf("%d", &T);
    for(int kase = 1; kase <= T; kase ++) {
        scanf("%d%d", &s, &n);
        for(int i = 0; i < n; i ++) scanf("%d", &x[i]);

        int last[maxn];
        memset(dist_to_next, -1, sizeof(dist_to_next));
        memset(last, -1, sizeof(last));
        for(int i = 0; i < n; i ++) {
            int u = x[i];
            if(last[u] != -1) {
                dist_to_next[last[u]] = i - last[u];
            }
            last[u] = i;
        }

        int vis[maxn];
        int ans = s;
        memset(vis, 0, sizeof(vis));
        for(int i = 0; i < n; i ++) {
            if(dist_to_next[i] != -1) {
                for(int j = (i + dist_to_next[i]) - s + 1; j <= i; j ++) {
                    int l = j % s;
                    if(j < 0) l = (j+s)%s;
                    if(vis[l] == 0) {
                        vis[l] = 1;
                        ans --;
                    }
                }
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值