POJ 1830 开关问题 高斯消元
基础的高斯消元解决异或方程问题。
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <stack> #include <map> #include <set> #include <climits> #include <iostream> #include <string> using namespace std; #define MP make_pair #define PB push_back typedef long long LL; typedef unsigned long long ULL; typedef vector<int> VI; typedef pair<int, int> PII; typedef pair<double, double> PDD; const int INF = INT_MAX / 3; const double eps = 1e-8; const LL LINF = 1e17; const double DINF = 1e60; const int maxn = 45; int a[maxn][maxn], n, s1[maxn], e1[maxn]; void Gauss() { for(int i = 0; i < n; i++) { int k = i; while(a[k][i] == 0 && k < n) k++; if(k >= n) continue; for(int j = 0; j <= n; j++) swap(a[i][j], a[k][j]); for(int j = 0; j < n; j++) if(i != j && a[j][i] != 0) { for(int k = 0; k <= n; k++) { a[j][k] ^= a[i][k]; } } } } void pa() { for(int i = 0; i < n; i++) { for(int j = 0; j <= n; j++) { printf("%d ", a[i][j]); } puts(""); } } int main() { int T; scanf("%d", &T); while(T--) { memset(a, 0, sizeof(a)); scanf("%d", &n); for(int i = 0; i < n; i++) scanf("%d", &s1[i]); for(int i = 0; i < n; i++) scanf("%d", &e1[i]); for(int i = 0; i < n; i++) if(s1[i] != e1[i]) a[i][n] = 1; for(int i = 0; i < n; i++) a[i][i] = 1; int ia, ib; while(scanf("%d%d", &ia, &ib)) { if(ia == 0 && ib == 0) break; ia--; ib--; a[ib][ia] = 1; } Gauss(); bool bad = false; int fcnt = 0, ans = 0; for(int i = 0; i < n; i++) { int nowsum = 0; for(int j = 0; j < n; j++) nowsum += a[i][j]; if(nowsum == 0 && a[i][n] != 0) bad = true; if(a[i][n] == 0 && nowsum == 0) fcnt++; } //printf("the answer is :"); if(bad) puts("Oh,it's impossible~!!"); else cout << (1LL << fcnt) << endl; } return 0; }