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\) 的数字个数。
- \(p \equiv 0(\bmod 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;
}