CF2067B 题解

闲话

本文同步发布在 cnblogs


容易发现,若想要让两个袋子物品相同,每种数字都应有偶数个。

这只是根据操作一得出的结论,我们还有操作二。

对于一个数字,我们有以下的贪心策略,其中 \(b_i\) 表示 \(i\) 在数组 \(a\) 中出现的次数,即一个桶:

  • \(b_i \ge 2\),可以转移 \(b_i - 2\) 个数字给 \(b_{i + 1}\),即 \(b_{i + 1} \gets b_{i + 1} + (b_i - 2)\)\(b_i \gets 2\)

  • 接下来,若 \(b_i\) 仍为奇数,即无解。

这个贪心需要证明,第二项显然,第一项证明如下:

首先,一个数只能留下偶数个数,这里我们留下了 \(2\) 个,符合性质。

其次,由于剩下的是偶数,转移的奇偶性是已经确定了的,在这种情况下,多继承一部分,可以更好地填上后面的空缺,不比原转移更少劣。

得到证明,实现代码:

#include<bits/stdc++.h>
using namespace std;
int t, n, a[1005], b[1005];
int main(){
    cin >> t;
    while(t --){
        int flag = 0;
        cin >> n;
        for(int i = 1; i <= n; i ++){
            b[i] = 0;
        }
        for(int i = 1; i <= n; i ++) cin >> a[i], b[a[i]] ++;
        for(int i = 1; i <= n; i ++){
            if(b[i] >= 2){
                b[i + 1] += (b[i] - 2);
                b[i] = 0;// 这里主要是为了应付下面两句不被判到,改成任意偶数均可
            }
            if(b[i] & 1){
                cout << "NO\n";
                flag = 1; break;
            }
        }
        if(!flag){
            cout << "YES\n";
        }
    }
    return 0;
}

posted on   zhangzirui66  阅读(12)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示