多校第六场的题目, 比赛时没什么想法, 后来看GYZ神犇的解题报告里用的是O(n ^ 2)的2 - SAT解法, 但本弱菜还是没想到如何构图, 后来看别人都是用dfs过的, 自己写了一版觉得还是挺好写的, 而且速度也很快, 但复杂度不知如何分析, 一开始觉得dfs应该会T的, 毕竟需要递归2000层, 后来想了想觉得这题有一定的特殊性, 因为题目只要求输出一组解, 而且如果相同同种颜色很多的话解的个数也会多, 所以dfs速度会比较快, 但准确的理论复杂度还是不知如何分析, 有时间再研究2-SAT解法吧。。。。。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>
#include <cctype>
#include <set>
#include <deque>
#include <map>
using namespace std;
inline int readint() {
char c = getchar();
while (!isdigit(c)) c = getchar();
int x = 0;
while (isdigit(c)) {
x = x * 10 + c - '0';
c = getchar();
}
return x;
}
int buf[10];
inline void writeint(int x) {
int p = 0;
if (x == 0) p++;
else while (x) {
buf[p++] = x % 10;
x /= 10;
}
for (int j = p - 1; j >= 0; j--)
putchar('0' + buf[j]);
}
const int N = 2005;
int cnt0[N], cnt1[N], sum[N];
int res[N], s0[N], s1[N], str[N];
int n;
bool ok = 0;
void dfs(int id, int sz0, int sz1) {
if (id == n + 1) {
for (int i = 1; i <= n; i++)
printf("%d", res[i]);
puts("");
ok = 1;
return;
}
if (cnt0[str[id]] < sum[str[id]] / 2 && (sz0 >= sz1 || str[id] == s1[sz0])) {
res[id] = 0;
cnt0[str[id]]++;
s0[sz0] = str[id];
dfs(id + 1, sz0 + 1, sz1);
if (ok) return;
cnt0[str[id]]--;
}
if (cnt1[str[id]] < sum[str[id]] / 2 && (sz1 >= sz0 || str[id] == s0[sz1])) {
res[id] = 1;
cnt1[str[id]]++;
s1[sz1] = str[id];
dfs(id + 1, sz0, sz1 + 1);
if (ok) return;
cnt1[str[id]]--;
}
}
int main() {
int test;
test = readint();
while (test--) {
n = readint();
for (int i = 1; i <= n; i++)
cnt0[i] = 0, cnt1[i] = 0, sum[i] = 0;
for (int i = 1; i <= n; i++)
str[i] = readint(), sum[str[i]]++;
ok = 0;
s0[1] = str[1];
cnt0[str[1]]++;
dfs(2, 2, 1);
}
return 0;
}