POJ 1830 开关问题 (高斯消元)

题目链接

题意:中文题,和上篇博客POJ 1222是一类题。

题解:如果有解,解的个数便是2^(自由变元个数),因为每个变元都有两种选择。

代码:

 

#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdio>
using namespace std;
int s[35],e[35],g[35][35],n;
int gauss()
{
    int row,col;
    for(row=0,col=0;row<n&&col<n;col++)
    {
        int id=row;
        for(int i=row;i<n;i++)
        if(g[i][col]) id=i;
        if(g[id][col])
        {
            for(int k=col;k<=n;k++)
            swap(g[id][k],g[row][k]);
            for(int i=row+1;i<n;i++)
            if(g[i][col])
            for(int k=col;k<=n;k++)
            g[i][k]^=g[row][k];
            row++;
        }
    }
    for(int i=row;i<n;i++)
    if(g[i][n]) return -1;
    return 1<<(n-row);
}
int main()
{
    //注意一定不要在主函数里定义n 这样会在输入的时候覆盖全局变量n
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        memset(g,0,sizeof(g));
        for(int i=0;i<n;i++)
        scanf("%d",&s[i]);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&e[i]);
            g[i][n]=s[i]^e[i];
            g[i][i]=1;
        }
        int a,b;
        for(;;)
        {
            scanf("%d%d",&a,&b);
            if(a==0&&b==0) break;
            //这里注意题目中的下标是从1开始的
            //而且ab不能写反 至于为什么不能写反还不清楚
            g[b-1][a-1]=1;
        }
        int ans=gauss();
        if(ans==-1)
        puts("Oh,it's impossible~!!");
        else
        printf("%d\n",ans);
    }
    return 0;
}

 

posted @ 2016-09-03 15:25  Ritchie丶  阅读(143)  评论(0编辑  收藏  举报