HDU 4421 bit magic
Question Link
Based on the question, the B array is given to see if a suitable A array can be constructed.
Idea: consider each binary digit of each number separately, and it becomes a 2-Sat question. Based on the formula in the question, create a 2-Sat edge, then each digit runs 2-Sat. If each digit matches yes, the other digit is no.
Code:
#include <cstdio>#include <cstring>#include <cstdlib>#include <vector>#include <algorithm>using namespace std;const int MAXNODE = 505;struct TwoSet {int n;vector<int> g[MAXNODE * 2];bool mark[MAXNODE * 2];int S[MAXNODE * 2], sn;void init(int tot) {n = tot * 2;for (int i = 0; i < n; i += 2) {g[i].clear();g[i^1].clear();}memset(mark, false, sizeof(mark));}void add_Edge(int u, int uval, int v, int vval) {u = u * 2 + uval;v = v * 2 + vval;g[u^1].push_back(v);g[v^1].push_back(u);}void delete_Edge(int u, int uval, int v, int vval) {u = u * 2 + uval;v = v * 2 + vval;g[u^1].pop_back();g[v^1].pop_back();}bool dfs(int u) {if (mark[u^1]) return false;if (mark[u]) return true;mark[u] = true;S[sn++] = u;for (int i = 0; i < g[u].size(); i++) {int v = g[u][i];if (!dfs(v)) return false;}return true;}bool solve() {for (int i = 0; i < n; i += 2) {if (!mark[i] && !mark[i + 1]) {sn = 0;if (!dfs(i)){for (int j = 0; j < sn; j++)mark[S[j]] = false;sn = 0;if (!dfs(i + 1)) return false;}}}return true;}} gao;const int N = 505;int n, b[N][N];bool solve() {for (int k = 0; k < 31; k++) {gao.init(n);for (int i = 0; i < n; i++)for (int j = 0; j < n; j++) {int tmp = (b[i][j]>>k)&1;if (i == j) {if (tmp) return false;}else if (i % 2 == 1 && j % 2 == 1) {if (tmp) gao.add_Edge(i, tmp, j, tmp);else {gao.add_Edge(i, tmp, i, tmp);gao.add_Edge(j, tmp, j, tmp);}}else if (i % 2 == 0 && j % 2 == 0) {if (tmp) {gao.add_Edge(i, tmp, i, tmp);gao.add_Edge(j, tmp, j, tmp);} else gao.add_Edge(i, tmp, j, tmp);} else {if (tmp) {gao.add_Edge(i, tmp, j, tmp);gao.add_Edge(i, !tmp, j, !tmp);} else {gao.add_Edge(i, tmp, j, !tmp);gao.add_Edge(i, !tmp, j, tmp);}}}if (!gao.solve()) return false;}return true;}int main() {while (~scanf("%d", &n)) {for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)scanf("%d", &b[i][j]);printf("%s\n", solve() ? "YES" : "NO");}return 0;}
HDU 4421 bit magic (2-Sat)