Educational Codeforces Round #51 C. Vasya and Multisets

http://codeforces.com/contest/1051/problem/C

现场自闭了。

问题

当一个数字 \(x\) 在一个多重集中出现的次数为 \(1\) 时,我们称 \(x\) 是好康的。 现在给定一个序列 \(S\),要求把 \(S\) 中的数字放到多重集 \(A\) 中或多重集 \(B\) 中,问是否存在一种方案使得两个多重集中的好康数字一样多,输出这个方案。

题解

考虑序列中的一个数字 \(x\),计它的出现次数为 \(c\)

\(c=1\) 时,它只能放到一边。

\(c=2\) 时,放到那边其实都一样,因为会抵消,忽略就好了。

\(c > 2\) 时,可以一边放 \(1\) 个,另一边放 \(c-1\) 个;或者随便放,不会对两边造成影响。

\(p\) 为出现 \(c=1\) 的数字个数,\(q\)\(c>2\) 的数字个数。

  1. \(p \equiv 0(\bmod 2)\) 时,平分即可。
  2. \(p \equiv 1(\bmod 2)\) 时,若 \(q=0\) 则无解,否则用出现多次的数字补一下。
#include <bits/stdc++.h>

using namespace std;

int n;
int s[110];
vector<int> vec[110];
int res[110];

int main() {
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &s[i]);
        vec[s[i]].push_back(i);
    }

    vector<int> one;
    vector<int> mult;
    for (int i = 1; i <= 100; i++) {
        if (1 == (int)vec[i].size()) {
            one.push_back(i);
        } else if (2 < (int)vec[i].size()) {
            mult.push_back(i);
        }
    }

    bool ans = true;
    if ((int)one.size() % 2 == 0) {
        int id = 0;
        for (int x : one) res[vec[x][0]] = id, id ^= 1;
        assert(id == 0);
    } else {
        if (mult.empty()) {
            ans = false;
        } else {
            int id = 0;
            for (int x : one) res[vec[x][0]] = id, id ^= 1;
            assert(id == 1);
            res[vec[mult[0]][0]] = 1;
        }
    }

    if (ans) { 
        puts("YES");
        string str;
        for (int i = 0; i < n; i++) str += (res[i] ? 'A' : 'B');
        cout << str << endl;
    } else {
        puts("NO");
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/hfccccccccccccc/p/9778956.html