(Solutions of equations + XOR problem switches Gaussian elimination) poj1222

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

The meaning of problems: Given a matrix of 01 5 × 6, which includes its own vertically and horizontally inverted state will change when the state of a point, because there is no equivalent to twice flip flip, then each point or not inverted, or flipped once, ultimately seeking to overturn what can make the all-zero matrix.

Ideas:

  Practice 1 (enumeration): because of the small data, can enumerate all possible first row, a total of six kinds << 1, each row after row in accordance with the decision, and this is determined by determining whether the last row of the condition proposal is feasible.

  2 approach (Gaussian elimination): To say clearly is now assumed that the matrix of 2 × 3, such as now is to achieve a target state:

    Now the state of the lamp in claim 6, the equivalent of six variables. Further six equations, respectively six points final state.

    For example, 0 for the first lamp, it is able to affect the second 0,1,3 lamp, so it is the equation: (1 * x0) ^ (1 * x1) ^ (0 * x2) ^ (1 * x3) ​​^ (0 * x4) ^ (0 * x5) = 0, (0 state of the right side of the equation represents the beginning 0 lamps).

    Similarly Equation 1 is the lamp of: (1 * x0) ^ (1 * x1) ^ (1 * x2) ^ (0 * x3) ^ (1 * x4) ^ (0 * x5) = 1.

    Equation 6 can be listed, and then solved using Gaussian elimination, XOR and general equations of linear equations is the same.

    For topic is 5 × 6 = 30 equations, respectively 30 shows a state variable of the lamp 30.

AC Code:

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

const int maxn=40;
int T,cas,a[maxn][maxn],ans[maxn];

void init(){
    memset(a,0,sizeof(a));
    memset(ans,0,sizeof(ans));
    for(int i=0;i<5;++i){
        for(int j=0;j<6;++j){
            int t=i*6+j;
            a[t][t]=1;
            if(i>0) a[t][t-6]=1;
            if(i<4) a[t][t+6]=1;
            if(j>0) a[t][t-1]=1;
            if(j<5) a[t][t+1]=1;
        }
    }
}

void Gauss(int equ,int var){
    int r=0,c=0;
    for(;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(a[Maxr][c]==0){
            --r;
            continue;
        }
        if(Maxr!=r){
            for(int i=c;i<=var;++i)
                swap(a[r][i],a[Maxr][i]);
        }
        for(int i=r+1;i<equ;++i){
            if(a[i][c]==0) continue;
            for(int j=c;j<=var;++j)
                a[i][j]^=a[r][j];
        }
    }
    for(int i=var-1;i>=0;--i){
        ans[i]=a[i][var];
        for(int j=i+1;j<equ;++j)
            ans[i]^=(a[i][j]&ans[j]);
    }
}

int main(){
    scanf("%d",&T);
    while(T--){
        init();
        for(int i=0;i<30;++i)
            scanf("%d",&a[i][30]);
        Gauss(30,30);
        printf("PUZZLE #%d\n",++cas);
        for(int i=0;i<5;++i){
            for(int j=0;j<6;++j){
                printf("%d",ans[i*6+j]);
                if(j!=5) printf(" ");
            }
            printf("\n");
        }
    }
    return 0;
}

 

Guess you like

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