CF Educational Codeforces Round 170 (Rated for Div. 2).C. New Game

题目

思路:如果没有限制 k 种数字的话,直接比较最长的连续的数字串(前后要么相等,要么相差 1)即可

限制了 k 种数字,我们只需要多添加一步,开一个二维数组,第一维存储一串连续的数字,第二维存储每个连续数字的个数

eg:1 1 2 3 7 7 8 8 9          --->        a[0] = 2 1 1, a[1] = 2 2 1

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>

using namespace std;

int T;

void solve()
{
    int n, k;
    cin >> n >> k;

    map<int, int> p;
    for (int i = 0; i < n; i ++ )
    {
        int x;
        cin >> x;
        p[x] ++ ;
    }

    vector<vector<int>> a(n + 1);
    int idx = -1, last = -1;
    for (auto t : p)
    {
        // 移到下一个坑位
        if (last + 1 != t.first)
        {
            idx ++ ;
            // 为前缀和做准备
            a[idx].push_back(0);
            a[idx].push_back(t.second);
        }
        // 在原来的坑位上尾加法
        else a[idx].push_back(t.second);

        last = t.first;
    }

    int ans = 0;
    for (auto t : a)
    {
        // 退出循环
        if (t.size() == 0) break;

        // 这里的 sz 包括了 添加的0元素
        int sz = t.size() - 1;
        for (int i = 1; i <= sz; i ++ ) t[i] += t[i - 1];

        if (k >= sz)
        {
            ans = max(ans, t[sz]);
            continue;
        }

        // 从0开始,保证了 前缀和 包括 第一个元素
        for (int i = 0; i + k <= sz; i ++ )
            ans = max(ans, t[i + k] - t[i]);
    }

    cout << ans << endl;
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    cin >> T;
    while (T -- )
    {
        solve();
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值