POJ 1830 开关问题 [高斯消元XOR]
和上两题一样
Input
输入第一行有一个数K,表示以下有K组测试数据。
每组测试数据的格式如下:
第一行 一个数N(0 < N < 29)
第二行 N个0或者1的数,表示开始时N个开关状态。
第三行 N个0或者1的数,表示操作结束后N个开关的状态。
接下来 每行两个数I J,表示如果操作第 I 个开关,第J个开关的状态也会变化。每组数据以 0 0 结束。
每组测试数据的格式如下:
第一行 一个数N(0 < N < 29)
第二行 N个0或者1的数,表示开始时N个开关状态。
第三行 N个0或者1的数,表示操作结束后N个开关的状态。
接下来 每行两个数I J,表示如果操作第 I 个开关,第J个开关的状态也会变化。每组数据以 0 0 结束。
注意判断无解别把if放错位置
我的now表示当前该哪个方程组了,一开始是1确定一个变量就+1,答案应该是$2^{n-now+1}$才行
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <bitset> using namespace std; const int N=30; inline int read(){ char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } int n,u,v; bitset<N> a[N]; void ini(){for(int i=1;i<=n;i++) a[i].reset();} int now; void Gauss(){ now=1; for(int i=1;i<=n;i++){ int j=now; while(j<=n&&!a[j][i]) j++; if(j==n+1) continue; if(j!=now) swap(a[now],a[j]); for(int k=1;k<=n;k++) if(k!=now&&a[k][i]) a[k]^=a[now]; now++; } } int main(){ freopen("in","r",stdin); int T=read(); while(T--){ n=read(); ini(); for(int i=1;i<=n;i++) a[i][n+1]=read(); for(int i=1;i<=n;i++) a[i][n+1]=a[i][n+1]==read()?0:1; for(int i=1;i<=n;i++) a[i][i]=1; while(true){ u=read();v=read(); if(u==0&&v==0) break; a[v][u]=1; } Gauss(); int flag=0; //for(int i=1;i<=n;i++) for(int j=1;j<=n+1;j++) printf("%d%c",a[i][j]==1,j==n+1?'\n':' '); for(int i=1;i<=n;i++) if(a[i][n+1]){ int f=0; for(int j=1;j<=n;j++) if(a[i][j]==1) f=1; if(f==0){flag=1;break;} } if(flag) puts("Oh,it's impossible~!!"); else printf("%d\n",1<<(n-now+1)); } }
Copyright:http://www.cnblogs.com/candy99/