POJ 1830
列出n个方程右边为最后的情况
每一行代表第几个灯的情况,每一行代表是否按第几个按钮写出方程即可。
1 #include <cstdio> 2 #include <cstring> 3 const int Maxn=100; 4 int M[Maxn][Maxn],Ans,a[Maxn],b[Maxn],p,q,KASE,n; 5 inline void Swap(int &x,int &y) {int t=x;x=y;y=t;} 6 inline bool Check(int x) 7 { 8 for (int i=1;i<=n;i++) if (M[x][i]) return false; 9 return true; 10 } 11 bool Gauss() 12 { 13 int Pos=1; 14 for (int i=1;i<=n;i++) 15 { 16 int k=0; 17 for (int j=Pos;j<=n;j++) if (M[j][i]) {k=j; break;} 18 if (k==0) continue; 19 for (int j=1;j<=n+1;j++) Swap(M[Pos][j],M[k][j]); 20 for (int j=1;j<=n;j++) 21 if (M[j][i] && j!=Pos) 22 for (int l=1;l<=n+1;l++) M[j][l]^=M[Pos][l]; 23 Pos++; 24 } 25 int cnt=0; 26 for (int i=1;i<=n;i++) 27 if (Check(i)) 28 { 29 if (M[i][n+1]) return false; 30 cnt++; 31 } 32 return Ans=(1<<cnt); 33 } 34 int main() 35 { 36 scanf("%d",&KASE); 37 for (int Kase=1;Kase<=KASE;Kase++) 38 { 39 scanf("%d",&n); 40 memset(M,0,sizeof(M)); 41 for (int i=1;i<=n;i++) scanf("%d",&a[i]); 42 for (int i=1;i<=n;i++) scanf("%d",&b[i]); 43 for (int i=1;i<=n;i++) M[i][n+1]=a[i]^b[i]; 44 for (int i=1;i<=n;i++) M[i][i]=1; 45 while (scanf("%d%d",&p,&q)!=EOF) 46 { 47 if (p==0 && q==0) break; 48 M[q][p]=1; 49 } 50 if (Gauss()) printf("%d\n",Ans); else puts("Oh,it's impossible~!!"); 51 } 52 return 0; 53 }