题意:
给出一些开关互相影响的关系,问从开关的初始状态到结束状态有多少种变换的方法。
题解:
对于每个开关可能会受1....i某写开关的影响,因此对于开关i列出一个列向量,列向量每个元素只有1或0,表示某个开关是否影响这个i开关,这样就n个开关组合成一个矩阵,结束状态也是一个列向量,这样就可以用高斯消元求解解的个数。
#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<queue>
#include<map>
#include<set>
using namespace std;
#define B(x) (1<<(x))
typedef long long ll;
const int oo=0x3f3f3f3f;
const ll OO=1LL<<61;
const int MOD=10007;
const int maxn=1000;
int maze[maxn][maxn];
int x[maxn];
int s[maxn],e[maxn];
int Gauss(int n,int m){
int r,c;
for(r=0,c=0;r<n&&c<m;r++,c++){
int id=r;
for(int i=r+1;i<n;i++){
if(maze[i][c]>maze[id][c]){
id=i;
}
}
if(id!=r){
for(int j=c;j<=m;j++){
swap(maze[id][j],maze[r][j]);
}
}
if(maze[r][c]==0){
r--;
continue;
}
for(int i=r+1;i<n;i++){
if(maze[i][c]!=0){
for(int j=c;j<=m;j++){
maze[i][j]^=maze[r][j];
}
}
}
}
for(int i=r;i<n;i++){
if(maze[i][c]!=0)return -1;
}
return B(c-r);
}
int main(){
//#define ON 1
#ifdef ON
freopen("E:\\read.txt","r",stdin);
#endif // ON
int T,n,a,b;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
memset(maze,0,sizeof maze);
for(int i=0;i<n;i++)scanf("%d",&s[i]);
for(int i=0;i<n;i++)scanf("%d",&e[i]);
for(int i=0;i<n;i++){
maze[i][n]=s[i]^e[i];
maze[i][i]=1;
}
while(scanf("%d %d",&a,&b)){
if(a==0&&b==0)break;
maze[b-1][a-1]=1;
}
int ans=Gauss(n,n);
if(ans==-1) printf("Oh,it's impossible~!!\n");
else printf("%d\n",ans);
}
return 0;
}
/**
*/