多校第六場的題目, 比賽時沒什麼想法, 後來看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;
}