poj1753 (高斯消元法求异或方程组)

Posted frankchen831x

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj1753 (高斯消元法求异或方程组)相关的知识,希望对你有一定的参考价值。

题目链接:http://poj.org/problem?id=1753

题意:经典开关问题,和poj1222一样,进行两次高斯消元即可,只用初始化的时候改一下初始状态。可能存在无解或多解的情况,多解要枚举自由变元的所有状态。

AC代码:

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdlib>
using namespace std;

const int maxn=20;
const int inf=0x3f3f3f3f;
int mp[5][5],a[maxn][maxn],x[maxn],equ,var,free_x[maxn];
char s[5];

void init(int p){
    memset(a,0,sizeof(a));
    for(int i=0;i<4;++i){
        for(int j=0;j<4;++j){
            int t=i*4+j;
            a[t][16]=p^mp[i][j];
            a[t][t]=1;
            if(i>0) a[t][(i-1)*4+j]=1;
            if(i<3) a[t][(i+1)*4+j]=1;
            if(j>0) a[t][i*4+j-1]=1;
            if(j<3) a[t][i*4+j+1]=1;
        }
    }
}

int Gauss(){
    int r=0,cnt=0;
    for(int c=0;r<equ&&c<var;++r,++c){
        int Maxr=r;
        for(int i=r+1;i<equ;++i){
            if(abs(a[i][c])>abs(a[Maxr][c]))
                Maxr=i;
        }
        if(Maxr!=r){
            for(int i=c;i<var+1;++i)
                swap(a[r][i],a[Maxr][i]);
        }
        if(!a[r][c]){
            --r;
            free_x[cnt++]=c;
            continue;
        }
        for(int i=r+1;i<equ;++i){
            if(!a[i][c]) continue;
            for(int j=c;j<var+1;++j)
                a[i][j]^=a[r][j];
        }
    }
    for(int i=r;i<equ;++i)
        if(a[i][var])
            return -1;
    return var-r;
}

int solve(int t){
    int ret=inf;
    for(int i=0;i<(1<<t);++i){
        int cnt=0;
        memset(x,0,sizeof(x));
        for(int j=0;j<t;++j){
            if((i>>j)&1){
                ++cnt;
                x[free_x[j]]=1;
            }
        }
        for(int j=var-t-1;j>=0;--j){
            int tmp=a[j][var],tp,ok=1;
            for(int k=j;k<var;++k){
                if(!a[j][k]) continue;
                if(ok){
                    ok=0;
                    tp=k;
                }
                else{
                    tmp^=x[k];
                }
            }
            x[tp]=tmp;
            cnt+=x[tp];
        }
        ret=min(ret,cnt);
    }
    return ret;
}

int main(){
    equ=var=16;
    for(int i=0;i<4;++i){
        scanf("%s",s);
        for(int j=0;j<4;++j)
            if(s[j]==b) mp[i][j]=0;
            else mp[i][j]=1;
    }
    init(0);
    int t1,t2,t3,t4;
    t1=Gauss();
    if(t1!=-1) t2=solve(t1);
    init(1);
    t3=Gauss();
    if(t3!=-1) t4=solve(t3);
    if(t1==-1&&t3==-1)
        printf("Impossible
");
    else
        printf("%d
",min(t2,t4));
    return 0;
}

 

以上是关于poj1753 (高斯消元法求异或方程组)的主要内容,如果未能解决你的问题,请参考以下文章

[POJ1753]Flip Game(异或方程组,高斯消元,枚举自由变量)

poj1753(高斯消元解mod2方程组)

fzu1704(高斯消元法解异或方程组+高精度输出)

[zz]高斯消元法解01异或方程组

线性方程直接求法——高斯消元法(一)

C++ 数学与算法系列之高斯消元法求解线性方程组