[CF1451E1] Bitwise Queries (Easy Version) - 構造
阿新 • • 發佈:2020-12-05
Description
互動題,用不超過 \(n+2\) 次操作猜出一個長度為 \(n\) 的陣列,每次可以指定兩個不同的下標,詢問這兩個位置的數的 AND 或 OR 或 XOR。
Solution
一個直觀的思路是先猜出一小部分數,進而通過異或操作得出剩下的。
猜一個是不行的,猜兩個似乎也是不行的。
考慮猜三個,我們可以用五個“方程”去求解前三個數,至於選取怎樣的組合有很多種方案,可以寫個暴力程式嘗試幾次或者手玩一下。
#include <bits/stdc++.h> using namespace std; void clamp(int &x) { x = x != 0; } bool check(int a, int b, int c, int u, int v, int x, int y, int z) { clamp(a); clamp(b); clamp(c); clamp(u); clamp(v); clamp(x); clamp(y); clamp(z); return u == (a ^ b) && v == (b ^ c) && x == (a | c) && y == (a & b) && z == (b & c); } void solve(int &a, int &b, int &c, int u, int v, int x, int y, int z, int bm) { for (int ia = 0; ia < 2; ia++) { for (int ib = 0; ib < 2; ib++) { for (int ic = 0; ic < 2; ic++) { if (check(ia, ib, ic, (u & bm) > 0, (v & bm) > 0, (x & bm) > 0, (y & bm) > 0, (z & bm) > 0)) { a += bm * ia; b += bm * ib; c += bm * ic; return; } } } } } int main() { int u = 0, v = 0, x = 0, y = 0, z = 0, n; cin >> n; cout << "XOR 1 2 \nXOR 2 3 \nOR 1 3 \nAND 1 2 \nAND 2 3" << endl; cout.flush(); cin >> u >> v >> x >> y >> z; int *a = new int[n + 5]; for (int i = 1; i <= 3; i++) a[i] = 0; for (int i = 1; i < n; i *= 2) solve(a[1], a[2], a[3], u, v, x, y, z, i); for (int i = 4; i <= n; i++) { cout << "XOR 1 " << i << endl; cout.flush(); cin >> a[i]; a[i] ^= a[1]; } cout << "! "; for (int i = 1; i <= n; i++) cout << a[i] << " "; cout << endl; }