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("");
}
}
搜索代码写了再更新。