大致的思路是通过询问 a,b,c 和 b,c,d(假设 k=3),判断 a 和 d 是否同奇偶,然后用并查集维护元素之间两两的奇偶异同关系。理论复杂度 O(n),但是每个点(包括样例)都是 tle。当然有可能是我第一次写交互题出的格式错误。检查了两天没检查出来,请求帮助。
#include <iostream>
const int N = 1009;
int n, k;
int ds[N << 1];
int res[N];
int seq[N];
int find(int x) { return ds[x]<0 ? x : (ds[x] = find(ds[x])); }
void merge(int x, int y) {
x = find(x), y = find(y);
if (x == y) return ;
if (ds[x] > ds[y]) std::swap(x, y);
ds[x] += ds[y], ds[y] = x;
}
bool judge(int x, int y) { return find(x) == find(y); }
int main() {
scanf("%d%d", &n, &k);
for (int i = 1; i <= n << 1; i++)
ds[i] = -1;
for (int i = 1; i <= n; i++) {
// printf("i = %d\n", i);
printf("?");
for (int j = 1; j <= k; j++) {
int t = i + j - 1;
if (t > n) t -= n;
printf(" %d", t);
}
puts("");
scanf("%d", res + i);
if (i == 1) continue;
int x = i - 1, y = i + k - 1;
if (y > n) y -= n;
// printf("(x, y) = (%d, %d)\n", x, y);
if (res[i-1] == res[i]) {
merge(x, y);
// puts("[merge]: (x, y)");
merge(x + n, y + n);
// puts("[merge]: (x+n, y+n)");
} else {
merge(x, y + n);
// puts("[merge]: (x, y+n)");
merge(x + n, y);
// puts("[merge]: (x+n, y)");
}
}
// puts("Ridiculous!");
for (int i = 2; i <= n; i++)
if (judge(1, i) == false)
seq[i] = 1;
int t = 0;
for (int i = 1; i <= k; i++)
t += seq[i];
if (res[1] != (t & 1)) t = 1;
else t = 0;
printf("!");
for (int i = 1; i <= n; i++)
printf(" %d", seq[i] ^ t);
puts("");
return 0;
}
提交记录:
https://atcoder.jp/contests/abc313/submissions/44395809
https://atcoder.jp/contests/abc313/submissions/44371539