POJ 1753 Flip Game 高斯消元

和1222,1681差不多

POJ 1222 高斯消元更稳

POJ 1681 高斯消元 枚举自由变元

equ = 16 ,var = 16的方程组

#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#define INF 1e9
using namespace std;

const int maxn = 20;
int a[maxn][maxn];
int x[maxn],fre[maxn];
int dx[]= {0,0,-1,0,1};
int dy[]= {0,-1,0,1,0};

void debug(int n)
{
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<n; j++)
            printf("%d ", a[i][j]);
        printf("  %d
", a[i][n]);
    }
    puts("**************************************************************");
}

void init()
{
    memset(a,0,sizeof(a));
    for(int i=0; i<4; i++)
        for(int j=0; j<4; j++)
            for(int k=0; k<5; k++)
            {
                int nx = i+dx[k];
                int ny = j+dy[k];
                if(nx>=0 && nx <4 && ny>=0 && ny<4) a[i*4+j][nx*4+ny] = 1;
            }
}

int Guass(int equ,int var)
{
//    debug(16);
    int row,col,num;
    num=row=col=0;
    while(row<equ && col<var)
    {
        //列非零主
        int r=row;
        for(int i=row; i<equ; i++)
            if(a[i][col]!=0)
            {
                r=i;
                break;
            }
        if(r!=row)
        {
            for(int j=col; j<var+1; j++)
                swap(a[row][j],a[r][j]);
        }
        if(a[row][col]==0)//说明有自由变元
        {
            fre[num++] = col;
            col++;
            continue;
        }
        //消元
        for(int i=row+1; i<equ; i++)
        {
            if(a[i][col]==0) continue;
            for(int j=col; j<var+1; j++)
                a[i][j]^=a[row][j];
        }
//        debug(16);
        row++;
        col++;
    }
    for(int i=row; i<equ; i++)
        if(a[i][var]!=0) return INF;
    int sta=1<<(col-row);//自由变元有col-row个
    int res=INF;
    for(int k=0; k<sta; k++) //枚举所有变元
    {
        int cnt=0;
        int index=k;
        for(int j=0; j<num; j++)
        {
            x[fre[j]]=(index&1);
            if(x[fre[j]]) cnt++;
            index>>=1;
        }
        for(int i=row-1; i>=0; i--)
        {
            x[i]=a[i][var];
            for(col=i+1; col<var; col++)
                x[i]^=(a[i][col]*x[col]);
            if(x[i])cnt++;
        }
        res=min(cnt,res);
    }
    return res;
}

int main()
{
//    freopen("in.txt","r",stdin);
    char s[10][10];
    for(int i=0; i<4; i++)
        scanf("%s", s[i]);
    init();
    for(int i=0; i<4; i++)
        for(int j=0; j<4; j++)
            a[i*4+j][16] = (s[i][j]=='b'? 0:1);
    int ans1 = Guass(16,16);
    init();
    for(int i=0; i<4; i++)
        for(int j=0; j<4; j++)
            a[i*4+j][16] = (s[i][j]=='w'? 0:1);
    int ans2 = Guass(16,16);
    if(min(ans1,ans2) == INF) puts("Impossible");
    else printf("%d
", min(ans1, ans2));
    return 0;
}
原文地址:https://www.cnblogs.com/pach/p/7300179.html