POJ 1222 高斯消元

来源:互联网 发布:淘宝客采集软件微信 编辑:程序博客网 时间:2024/05/21 09:15

题意:
给你一个5*6的矩阵,你可以在任意位置对这个位置及其上下左右(如果有的话)进行xor【读作:叉欧二 ( :-D) 】操作,求解在哪些地方进行。
思路:
0. 一个显而易见就超时的方法(2^30),枚举第i个灯是开是关 但为第一种方法提供了思路
1.好像可以枚举第一行,然后通过递推算中间的几行,判断最后一行成不成立。
2.高斯消元,30个异或方程。

自己写得第一发高斯消元(虽然代码比较冗长,但自己yy出来很鸡冻)

// by Sirius_Ren#include <cstdio>#include <cstring>using namespace std;int eli[35][35],ans[31],x[32],cases,tot;void solve(){    for(int i=1;i<=30;i++)    if(~ans[i]&&eli[tot][i])eli[tot][31]=(eli[tot][31]+ans[i])%2;    for(int i=1;i<=30;i++)        if(eli[tot][i]&&ans[i]==-1)ans[i]=eli[tot][31];    tot--;}int main(){    scanf("%d",&cases);    for(int ii=1;ii<=cases;ii++){        memset(ans,-1,sizeof(ans));        memset(x,0,sizeof(x));        memset(eli,0,sizeof(eli));        tot=30;        for(int i=1;i<=30;i++)            scanf("%d",&eli[i][31]);        for(int i=1;i<=30;i++){            eli[i][i]=1;            if(i-6>0)eli[i][i-6]=1;            if(i+6<=30)eli[i][i+6]=1;            if(i%6)eli[i][i+1]=1;            if(i%6!=1)eli[i][i-1]=1;        }        for(int i=1;i<=29;i++)            for(int l=1;l<=30;l++)            if(eli[i][l]&&!x[l]){                x[l]=i;                for(int j=i+1;j<=30;j++)                    if(eli[j][l])                        for(int k=1;k<=31;k++)                            eli[j][k]^=eli[i][k];                break;            }        solve();        for(int i=29;i>=1;i--)            for(int j=1;j<=30;j++)                if(x[j]==i){                    solve();                    break;                }        printf("PUZZLE #%d\n",ii);        for(int i=1;i<=30;i++){            if(i%6)            printf("%d ",ans[i]);            else printf("%d\n",ans[i]);        }    }}
0 0
原创粉丝点击