您的位置:首页 > 其它

2000: 棋盘开关灯游戏 - 高斯消元|搜索

2016-01-31 10:16 316 查看
2000: 【高级算法】棋盘开关灯游戏

时间限制: 1 Sec 内存限制: 128 MB

提交: 37 解决: 23

[提交][状态][我的提交]

题目描述

一个棋盘状的开关阵列,排成5行6列。每个开关同时也是一个灯。按下一个开头后,受控制的灯就会改变状态:开->关,关->开。受控制的规则如下:

(1)角上的开关控制相邻的3个灯,如下图左上角的开关

(2)边上的开关控制相邻的4个灯,如下图底边的开关

(3)中间的开头控制相邻的5个灯,如下图第2行的开关

本题要解决的问题是:给出棋盘的初始状态,请确定按下哪些开关,使得棋盘上的所有灯就熄灭。

输入

第1行:1个整数n,表示测试数据的组数

接下来n组数据,每组5行,每行6个空格分开的整数,0表示关,1表示开。

输出

每组数据,输出一个5行6列的01阵列,0表示不按某个开关,1表示要按某个开关

每组数据之间用一个空行分隔

样例输入

2

0 1 1 0 1 0

1 0 0 1 1 1

0 0 1 0 0 1

1 0 0 1 0 1

0 1 1 1 0 0

0 0 1 0 1 0

1 0 1 0 1 1

0 0 1 0 1 1

1 0 1 1 0 0

0 1 0 1 0 0

样例输出

1 0 1 0 0 1

1 1 0 1 0 1

0 0 1 0 1 1

1 0 0 1 0 0

0 1 0 0 0 0

1 0 0 1 1 1

1 1 0 0 0 0

0 0 0 1 0 0

1 1 0 1 0 1

1 0 1 1 0 1

高斯消元异或方程:(0^1=1,1^1=0 => 关^改变状态=开 开^改变状态=关 )

未知数是对于每个灯的开关状态

方程根据每个灯受到的其他灯的影响列出

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 30
const int n=5,m=6;
int dir[10][3]={{0,0},{0,1},{0,-1},{1,0},{-1,0}};
int a[MAXN+10][MAXN+10],id[MAXN+10][MAXN+10];

void Debug()
{
for(int i=1;i<=n*m;i++){
for(int j=1;j<=m*n+1;j++)
printf("%d ",a[i][j]);
printf("\n");
}
}
void read()
{
int x,y;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[id[i][j]][n*m+1]);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
for(int k=0;k<5;k++){
x=i+dir[k][0],y=j+dir[k][1];
if(x>=1&&x<=n&&y>=1&&y<=m)
a[id[x][y]][id[i][j]]=1;
}
}
void GJ_elimination(int equ,int var,int &row,int &col)
{
int mx;
for(row=col=1;row<=equ&&col<=var;row++,col++){
mx=row;
for(int i=row+1;i<=equ;i++){
if(a[i][col]>a[mx][col])
mx=i;
if(a[mx][col]==1)
break;
}
if(mx!=row)
swap(a[row],a[mx]);
if(a[row][col]==0){ //本题有唯一解,这句if可以不要
row--;
continue;
}
for(int i=1;i<=equ;i++){
if(i==row||a[i][col]==0)
continue;
for(int j=var+1;j>=1;j--)
a[i][j]^=a[row][j];
}
}
}
void Gauss_Jordan(int equ,int var)
{
int row,col;
GJ_elimination(equ,var,row,col);
}
int main()
{
int T;
scanf("%d",&T);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
id[i][j]=(i-1)*m+j;//,printf("%d\n",id[i][j]);
while(T--){
memset(a,0,sizeof a);
read();
Gauss_Jordan(n*m,n*m);
for(int i=1;i<=n*m;i++){
printf("%d",a[i][n*m+1]);
if(i%m==0) printf("\n");
else printf(" ");
}
puts("");
}
}


搜索代码写了再更新。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: