POJ 1830 开关问题 [高斯消元XOR]

和上两题一样

Input

输入第一行有一个数K,表示以下有K组测试数据。 
每组测试数据的格式如下: 
第一行 一个数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));
    }
}

 

 
posted @ 2017-02-17 16:28  Candy?  阅读(271)  评论(0编辑  收藏  举报