[高斯消元] poj 1753 Flip Game

来源:互联网 发布:国密算法性能测试 编辑:程序博客网 时间:2024/06/10 20:04

题意:

点击棋子,棋子本身和四周都会变色。问变全白或者全黑的最少步数。


构造16个方程组求解,需要枚举自由基。

#include"cstdlib"#include"cstdio"#include"cstring"#include"cmath"#include"queue"#include"algorithm"#include"iostream"using namespace std;int equ,var;int a[17][17];        //增广矩阵int x[17];            //x的解系int nofree_num,ans;   //nofree_num 为非自由元的数量void debug()   //调试{    int i,j;    for(i=0; i<equ; i++)    {        for(j=0; j<=var; j++) printf("%d ",a[i][j]);        puts("");    }    puts("");}void ok(int tep,int x,int y){    if(x<0||y<0||x>=4||y>=4) return;    a[tep][x*4+y]=1;    return;}void build()    //构造初始系数矩阵{    int i,j;    for(i=0; i<4; i++)    {        for(j=0; j<4; j++)        {            int tep=i*4+j;            ok(tep,i,j);            ok(tep,i,j+1);            ok(tep,i,j-1);            ok(tep,i+1,j);            ok(tep,i-1,j);        }    }}void dfs(int p)   //无穷解的情况下 枚举不定元{    if(p<nofree_num)    {        int i,j;        for(i=nofree_num-1; i>=0; i--)        {            int tep=a[i][var];            for(j=i+1; j<var; j++) tep^=a[i][j]*x[j];            x[i]=tep/a[i][i];        }        int sum=0;        for(i=0;i<equ;i++) sum+=x[i];        ans=min(ans,sum);        return ;    }    x[p]=0;    dfs(p-1);    x[p]=1;    dfs(p-1);}int gauss(){    int i,j,k,row,col;    for(row=0,col=0; row<equ&&col<var ; row++,col++)   //将系数矩阵化为上三角矩阵    {        for(i=row; i<equ; i++) if(a[i][col]) break;        if(i==equ)        {            row--;            continue;        }        for(j=0; j<=var; j++) swap(a[i][j],a[row][j]);        for(i=row+1; i<equ; i++)        {            if(a[i][col])            {                for(j=col; j<=var; j++)                    a[i][j]^=a[row][j];            }        }    }    nofree_num=row;    for(i=row; i<equ; i++) if(a[i][var]) return -1; // 无解    for(i=0; i<equ; i++)            //使得列和行对应(在之前不出现零列)    {        if(a[i][i]==0)        {            for(j=i+1; j<var; j++)            {                if(a[i][j]) break;            }            if(j==var) break;            for(k=0; k<equ; k++) swap(a[k][i],a[k][j]);        }    }    if(var-nofree_num)                 //无穷解    {        ans=999999999;        dfs(var-1);        return ans;    }    int sum=0;                         //唯一解 直接回代求解    for(i=row-1; i>=0; i--)    {        int tep=a[i][var];        for(j=i+1; j<var; j++) tep^=a[i][j]*x[j];        x[i]=tep/a[i][i];        sum+=x[i];    }    return sum;}int main(){    char v[6][6];    while(cin>>v[0])    {        int i,j;        int f1,f2;        equ=var=16;        for(i=1; i<4; i++) cin>>v[i];        memset(a,0,sizeof(a));        build();        for(i=0; i<4; i++)        {            for(j=0; j<4; j++)            {                if(v[i][j]=='w') a[i*4+j][var]=0;                else a[i*4+j][var]=1;            }        }        f1=gauss();        memset(a,0,sizeof(a));        build();        for(i=0; i<4; i++)        {            for(j=0; j<4; j++)            {                if(v[i][j]=='w') a[i*4+j][var]=1;                else a[i*4+j][var]=0;            }        }        f2=gauss();        if(f1==-1&&f2==-1)        {            puts("Impossible");            continue;        }        if(f1==-1) printf("%d\n",f2);        else if(f2==-1) printf("%d\n",f1);        else printf("%d\n",min(f1,f2));    }}


0 0
原创粉丝点击