高斯消元求解异或方程组
Posted 033000-
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高斯消元求解异或方程组相关的知识,希望对你有一定的参考价值。
POJ1830 开关问题
对于解异或方程组,系数可以采用二进制压缩,如果系数太多可以使用bitset,但是如果少一点就可以使用下述的写法,更加简单快速
使用bitset的写法更正常的没什么区别,只是对应的消除变为异或操作,另外行变换也会更加简单
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int a[100], n, t, ans; int main() { cin >> t; while (t--) { cin >> 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; // a[i][i] = 1;- } int x, y; while (~scanf("%d%d", &x, &y) && x && y) { a[y] |= 1 << x; // a[y][x] = 1; } ans = 1; for (int i = 1; i <= n; i++) { // 找到最大的一个a[i],即主元位数最高的a[i] for (int j = i + 1; j <= n; j++) if (a[j] > a[i]) swap(a[i], a[j]); // 消元完毕,有i-1个主元,n-i+1个自由元 if (a[i] == 0) { ans = 1 << (n - i + 1); break; } // 出现0=1的方程,无解 if (a[i] == 1) { ans = 0; break; } // a[i]最高位的1作为主元,消去其他方程该位的系数 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 cout << ans << endl; } }
以上是关于高斯消元求解异或方程组的主要内容,如果未能解决你的问题,请参考以下文章
高斯消元法求解异或方程组: cojs.tk 539.//BZOJ 1770 牛棚的灯