分析:
这道题和poj1222大同小异
还是异或方程求解
唯一不同的就是,需要计算方案数
这就和那些不确定的元素有关了
每个不定元都有两种选择:开或关
所以方案数就是
2^(不定元个数)
怎么确定有没有解呢
for (int i=n;i>=1;i--)
if (a[i][n+1]!=0&&a[i][i]==0)
return 0;
不要忘了now++
注意题目描述中:
每行两个数I J,表示如果操作第 I 个开关,第J个开关的状态也会变化
也就是说第I决定第J个,所以a[J][I]=1
所以在列方程的时候,一定要找好对应关系
这再一次说明了那条真理
//这里写代码片
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int cnt,n;
int mp1[35],mp2[35];
int a[35][35];
int gauss()
{
cnt=0;
int now=1,to;
for (int i=1;i<=n;i++)
{
for (to=now;to<=n;to++)
if (a[to][i]) break;
if (to>n) //不定元
{
cnt++;
now++;
continue;
}
if (to!=now)
for (int j=1;j<=n+1;j++)
swap(a[to][j],a[now][j]);
for (int j=1;j<=n;j++)
if (j!=now&&a[j][i])
for (int k=1;k<=n+1;k++)
a[j][k]^=a[now][k];
now++;
}
for (int i=n;i>=1;i--)
if (a[i][n+1]!=0&&a[i][i]==0)
return 0;
return 1;
}
int main()
{
int T;
scanf("%d",&T);
while (T--)
{
scanf("%d",&n);
memset(a,0,sizeof(a));
for (int i=1;i<=n;i++) scanf("%d",&mp1[i]);
for (int i=1;i<=n;i++) scanf("%d",&mp2[i]);
int x,y;
scanf("%d%d",&x,&y);
while (x&&y)
{
a[y][x]=1;
scanf("%d%d",&x,&y);
}
for (int i=1;i<=n;i++)
{
a[i][i]=1;
a[i][n+1]=mp1[i]^mp2[i];
}
if (gauss())
{
printf("%d\n",(1<<cnt));
}
else printf("Oh,it's impossible~!!\n");
}
return 0;
}