Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 8652 | Accepted: 3401 |
Description
Input
每組測試數據的格式如下:
第一行 一個數N(0 < N < 29)
第二行 N個0或者1的數,表示開始時N個開關狀態。
第三行 N個0或者1的數,表示操作結束後N個開關的狀態。
接下來 每行兩個數I J,表示如果操作第 I 個開關,第J個開關的狀態也會變化。每組數據以 0 0 結束。
Output
Sample Input
2 3 0 0 0 1 1 1 1 2 1 3 2 1 2 3 3 1 3 2 0 0 3 0 0 0 1 0 1 1 2 2 1 0 0
Sample Output
4 Oh,it's impossible~!!
Hint
一共以下四種方法:
操作開關1
操作開關2
操作開關3
操作開關1、2、3 (不記順序)
題目大意:
如題:
題目思路:
高斯消元模板題,答案爲1<<自由元數,因爲對於每個自由元即該列全爲0,開關
不管是開還是關都沒有影響
AC代碼:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n;
int a[35][35];
int S[35],T[35];
int GaussElimination()
{
int i,j,k;
for(i=1,j=1;j<=n;j++)
{
int k = i;
while(k<=n&&a[k][j]==0)k++;
if(a[k][j])
{
for(int l = 1;l<=n+1;l++)swap(a[i][l],a[k][l]);
for(int l=i+1;l<=n;l++)
{
if(a[l][j])
{
for(int ii=j;ii<=n+1;ii++)
{
a[l][ii]^=a[i][ii];
}
}
}
i++;
}
}
for(j=i;j<=n;j++)
{
if(a[j][n+1])return -1;
}
return n-i+1;
}
int main()
{
int t;cin>>t;
while(t--)
{
memset(a,0,sizeof(a));
cin>>n;
for(int i=1;i<=n;i++)scanf("%d",&S[i]);
for(int j=1;j<=n;j++)
{
scanf("%d",&T[j]);
a[j][j] = 1;
a[j][n+1] = S[j]^T[j];
}
int x,y;
while(scanf("%d%d",&x,&y),x+y)
{
a[y][x] = 1;
}
int ans = GaussElimination();
if(ans==-1)printf("Oh,it's impossible~!!\n");
else printf("%d\n",1<<ans);
}
return 0;
}