POJ1830开关问题

Posted white_hat_hacker

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ1830开关问题相关的知识,希望对你有一定的参考价值。

这题答案就是2^自由元的数目,原因是自由元可以取1或者0,所以就是ans<<1

由于只要求自由元的数目,所以高斯消元可以直接消后面的,不做前面的了,对答案没有影响

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<algorithm>
 4 #include<cstring>
 5 #define MAXN 35
 6 using namespace std;
 7 int a[MAXN][MAXN];
 8 int gauss(int m,int n){
 9     int ret=0,line=1;
10     for(int k=1;k<=m;k++){
11         int i=line;
12         while(i<=m){if(a[i][k])break;i++;}
13         if(i>m){ret++;continue;}//自由元 
14         if(i!=line){for(int j=k;j<=n;j++)swap(a[i][j],a[line][j]);}
15         for(i=line+1;i<=m;i++){
16             if(a[i][k]){
17                 for(int j=k;j<=n;j++){
18                     a[i][j]^=a[line][j];
19                 }
20             }
21         }
22         line++;
23     }
24     for(int i=line;i<=m;i++)if(a[i][n])return -1;
25     //最后一定都消成0了,所以a[i][n]必须为0才符合题意 
26     return ret;
27 }
28 int n;
29 void solve(){
30     memset(a,0,sizeof(a));
31     scanf("%d",&n);
32     for(int i=1;i<=n;i++)scanf("%d",&a[i][n+1]);
33     int x,y;
34     for(int i=1;i<=n;i++){scanf("%d",&x);a[i][n+1]^=x;}
35     for(int i=1;i<=n;i++){a[i][i]=1;}
36     while(1){
37         scanf("%d%d",&x,&y);
38         if(!x&&!y)break;
39         a[y][x]=1;
40     }
41     int ans=gauss(n,n+1);
42     if(-1==ans)printf("Oh,it‘s impossible~!!\n");
43     else printf("%d\n",1<<ans);
44 }
45 int main()
46 {
47 //    freopen("data.in","r",stdin);
48     int T;
49     scanf("%d",&T);
50     while(T--){
51         solve();
52     }
53     return 0;
54 }

 

以上是关于POJ1830开关问题的主要内容,如果未能解决你的问题,请参考以下文章

POJ 1830 开关问题

poj 1830 开关问题

POJ 1830 开关问题

POJ 1830 开关问题 高斯消元,自由变量个数

POJ 1830 开关问题

poj1830(求解xor方程组)