POJ1830 开关问题 高斯消元 异或
设xixi表示第ii个开关的操作情况,那么xi=1xi=1为按了这个开关,否则xi=0xi=0表示这个开关并没有按下去,那么我们接着统计ai,jai,j表示第i个开关和第j个开关的联系情况,ai,j=1ai,j=1表示按下j会影响i的状态,否则就是不会影响,即ai,j=0ai,j=0,特殊地一个点就是,ai,i=1ai,i=1,因为我们本身肯定会影响本身.
这里由于系数是1,0,直接进行状态压缩。
高斯消元过程种,把加法,减法替换成异或,不执行乘法,最终可以得到对应的简化阶梯型矩阵。 若存在形如 0 = 1的方程,则方程组无解。
int a[100], n, T, ans; int main() { scanf("%d", &T); while (T--) { scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); for (int i = 1, j; i <= n; i++) { scanf("%d", &j); a[i] ^= j; a[i] |= 1 << i; } int x, y; while (scanf("%d%d", &x, &y) && x && y) { a[y] |= 1 << x; } ans = 1; for (int i = 1; i <= n; i++) { for (int j = i + 1; j <= n; j++) if (a[j] > a[i]) swap(a[i], a[j]); if (!a[i]) { ans = 1 << (n - i + 1); break; } if (a[i] == 1) { ans = 0; break; } for (int k = n; k; k--) { if (a[i] >> k & 1) { for (int j = 1; j <= n; j++) if (i != j && (a[j] >> k & 1)) a[j] ^= a[i]; break; } } } if (ans == 0) puts("Oh,it's impossible~!!"); else printf("%d\n", ans); } }