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 => 关^改变状态=开 开^改变状态=关 )
未知数是对于每个灯的开关状态
方程根据每个灯受到的其他灯的影响列出
搜索代码写了再更新。
时间限制: 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(""); } }
搜索代码写了再更新。
相关文章推荐