2074. 倒计数 知识点:双指针 哈希 KMP

30 阅读1分钟

2074. 倒计数 - AcWing题库

双指针

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL N=2e5+10;
LL a[N];

int main() {
    int t;
    cin >> t;
    for (int cs = 1; cs <= t; cs++) { // 使用cs来表示Case的编号
        int n, k, cnt = 0;
        cin >> n >> k;
        for (int i = 0; i < n; i++) cin >> a[i];
        
        for (int i = 0; i < n; i++) {
            if (a[i] == k) {
                LL sum = 0, j = i;
                for (LL num = k; num >= 1; num--) {
                    if (j >= n || a[j] != num) break; // 如果数组结束或元素不匹配,则跳出循环
                    sum += a[j++];
                }
                if (j - i == k) cnt++; // 如果找到了一个完整的倒计数序列,则增加计数
            }
        }
        cout << "Case #" << cs << ": " << cnt << endl;
    }

    return 0;
}

队列

#include <cstring>
#include <algorithm>
#include <iostream>

using namespace std;

const int N = 200010;

int n, m;
int a[N], q[N];

int main()
{
    int T;
    cin >> T; //多组数据
    for (int t = 1; t <= T; t ++)
    {
        cin >> n >> m;    //输入n个数,倒计时数

        int tt = -1, hh = 0;  //数组队列初始化
        for (int i = 1; i <= n; i ++)
        {
            cin >> a[i]; 
            if (a[i] == m) q[++ tt] = i; //因为倒计时出现第一个数肯定是m,所以队列存下所有是m的下标
        }

        int res = 0;  //答案
        while (hh <= tt)   //队列不空
        {
            int s = q[hh ++];   //队头弹出,s表示下标
            int v = a[s];   //b表示s下标的值
            //以为s的位置是倒计时最大的数m,所以下标从s + 1的位置开始搜
            //每一个数是上一个数-1
            for (int i = s + 1; i <= n; i ++)  
            {
                if (a[i] == v - 1) v = a[i]; //如果当前数是上一个数-1,那就是正确的,将a[i]赋值给v
                else break;  //如果不是上一个数-1,那就直接break,不会进行了
            }
            if (v == 1) res ++;   //倒计时结束,v的值肯定是1,是1的话,res ++
        }
        printf("Case #%d: %d\n",t, res);   //最后按照样例格式输入答案
    }
    return 0;
}