poj EXTENDED LIGHTS OUT 高斯消元

来源:互联网 发布:ubuntu查看分区挂载点 编辑:程序博客网 时间:2024/06/05 16:54

题意:有5*6的矩阵分别表示30盏灯,每个位置为0表示关,为1表示开。每改变一盏灯的同时也会改变它上下左右的四盏灯,问要改变那些灯能把所有灯都观赏。

分析:
第一次写高斯消元,发现其实也没什么难的。其实就是把分别每一个未知数在其他方程里面消去然后就得到了一组解。
可以对每盏灯都建立一个方程,那么就有一个30个方程30个未知数的方程组,很明显这只有唯一的一组解,那么只要高斯消元搞一搞就好了。

代码:

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std;int a[40][40],dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};void gauss(int n,int m){    for (int i=1;i<=n;i++)    {        int l=i;        for (int j=l+1;j<=n;j++)            if (a[j][i])            {                l=j;                continue;            }        if (l!=i)            for (int j=1;j<=m;j++)                swap(a[i][j],a[l][j]);        for (int j=1;j<=n;j++)            if (j!=i&&a[j][i])                for (int k=1;k<=m;k++)                    a[j][k]^=a[i][k];    }}int main(){    int t;    scanf("%d",&t);    for (int l=1;l<=t;l++)    {        printf("PUZZLE #%d\n",l);        memset(a,0,sizeof(a));        for (int i=1;i<=5;i++)            for (int j=1;j<=6;j++)            {                int x;                scanf("%d",&x);                a[(i-1)*6+j][31]=x;            }        for (int i=1;i<=5;i++)            for (int j=1;j<=6;j++)            {                a[(i-1)*6+j][(i-1)*6+j]=1;                for (int k=0;k<4;k++)                {                    int p=i+dx[k],q=j+dy[k];                    if (p<1||p>5||q<1||q>6) continue;                    a[(i-1)*6+j][(p-1)*6+q]=1;                }            }        gauss(30,31);        for (int i=1;i<=5;i++)        {            for (int j=1;j<=6;j++)                printf("%d ",a[(i-1)*6+j][31]);            cout<<endl;        }    }    return 0;}
0 0
原创粉丝点击