(Template) poj1681 divergent Gaussian elimination or the equation (no solution, a unique solution, multiplicity)

Topic link: https: //vjudge.net/problem/POJ-1681

The meaning of problems: similar poj1222, 01 there is an n × n matrix, a point will be inverted vertically and horizontally reversing that includes its own point, a minimum number of points required matrix inversion enables all zeros.

Ideas:

  The same can enumerate the status of the first line, do not say here.

  Gauss elimination method to solve this question, the status of each point represents a variable, then there are n * n equations, equation n * n variables, using Gaussian elimination to solve, there may be no solution, the only solution, in the case of multiple solutions. When multiple solutions to enumerate the arguments of a free state.

AC Code:

/*
    poj1681
    Switch problem, Gaussian elimination method for solving equations XOR
    It requires at least to flip the switch matrix such that the whole 0
    There is no solution, a unique solution, multiple solutions situations
    To enumerate freedom argument multi-state solution
   */
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<cstring>
using namespace std;

const int maxn=250;
const int inf=0x3f3f3f3f;
int T,n,equ,var,a[maxn][maxn],x[maxn],free_xx[maxn];
int ans;
char s[20];

void init(){    //初始化
    memset(a,0,sizeof(a));
    for(int i=0;i<n;++i){
        for(int j=0;j<n;++j){
            int t=i*n+j;
            a[t][t]=1;
            if(i>0) a[t][(i-1)*n+j]=1;
            if(i<n-1) a[t][(i+1)*n+j]=1;
            if(j>0) a[t][i*n+j-1]=1;
            if(j<n-1) a[t][i*n+j+1]=1;
        }
    }
}

int Gauss(){
    int r=0,cnt=0;  //cnt表示自由变元个数
    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[Maxr][i],a[r][i]);
        }
        if(!a[r][c]){
            --r;
            free_xx[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 & lt; I <EQU; ++ I)
         IF (A [I] [ var ])
             return - . 1 ;     // no solution 
    return  var -R & lt;          // returns the number of arguments freedom, cnt = -R & lt var 
}

int solve(int t){
    ANS = INF;
     for ( int I = 0 ; I <( . 1 << T); I ++) {   // Enumeration Arguments free state 
        int CNT = 0 ;         // number to flip 
        memset (x, 0 , the sizeof (X));
         for ( int J = 0 ; J <T; ++ J) {
             IF ((I >> J) & . 1 ) {
                 ++ CNT;
                x[free_xx[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];
        }
        ANS = min (ANS, CNT);   // get the smallest 
    }
     return ANS;
}

int main () {
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        init();
        equ=var=n*n;
        for(int i=0;i<n;++i){
            scanf("%s",s);
            for(int j=0;j<n;++j)
                if(s[j]=='y') a[i*n+j][n*n]=0;
                else a[i*n+j][n*n]=1;
        }
        int t=Gauss();
        if(t==-1)
            printf("inf\n");
        else 
            printf("%d\n",solve(t));
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/FrankChen831X/p/11770528.html