POJ1222 高斯消元 枚举 xingxing在努力
关于本题, 有两种做法, 一种就是暴力枚举第一行的操作, 然后顺势确定下面2-5行的操作,最后看看最后一行是否满足要求即可。。代码如下
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; int Map[10][10]; int f[10][10]; int dr[5] = {0, 0, -1, 1, 0}; int dc[5] = {1, -1, 0, 0, 0}; inline bool inside(int x, int y) { return (x>=0&&x<5&&y>=0&&y<6); } int getcolor(int x, int y) //获取坐标(x, y)的状态 其与他自己和周围的四个方块有关 { int col = Map[x][y]; for(int i=0; i<5; i++) { int nx=x+dr[i], ny=y+dc[i]; if(inside(nx, ny)) col+=f[nx][ny]; } return col%2; } bool solve() { for(int i=1; i<5; i++) //根据第一行确定下面几行的操作 { for(int j=0; j<6; j++) if(getcolor(i-1, j)==1) f[i][j] = 1; } bool res = true; for(int j=0; j<6; j++) //查看最后一行是不是全部关着 if(getcolor(4, j)==1) { res = false; break; } return res; } int main() { //freopen("in.txt", "r", stdin); int T, kase=0; scanf("%d", &T); while(T--) { //memset(f, 0, sizeof(0)); //wa出新高度了 == for(int i=0; i<5; i++) for(int j=0; j<6; j++) scanf("%d", &Map[i][j]); for(int i=0; i<(1<<6); i++) //枚举第一行的操作 { memset(f, 0, sizeof(f)); //记得清0 int st = i; for(int j=0; j<6; j++) { if((st&1)==1) f[0][j]=1; else f[0][j] = 0; st>>=1; } if(solve()) break; //memset(f, 0, sizeof(f)); } printf("PUZZLE #%d\n", ++kase); for(int i=0; i<5; i++) { for(int j=0; j<6; j++) printf("%d%c", f[i][j], j==5?'\n':' '); } } return 0; }
除了上面的方法外还有一种列方程的方法解决本题。代码如下
#include <cstring> #include <algorithm> #include <cstdio> using namespace std; int a[35][35]; int ans[35]; void gauss() { for(int i=0; i<30; i++) //开始消第i个元 { int k = i; for(; k<30; k++) //找到一行,这一行的第i列不为0 if(a[k][i]!=0) break; for(int j=0; j<=30; j++) //交换这一行和第i行 swap(a[i][j], a[k][j]); for(int j=0; j<30; j++) //利用第i行消去其他行第i列的1 if(i!=j && a[j][i]) for(int k=0; k<=30; k++) a[j][k] = a[j][k] ^ a[i][k]; } for(int i=0; i<30; i++) ans[i] = a[i][30]; } int main() { int T, kase=0; scanf("%d", &T); while(T--) { memset(a, 0, sizeof(a)); for(int i=0; i<30; i++) scanf("%d", &a[i][30]); for(int i=0; i<30; i++) { a[i][i] = 1; if(i%6!=0) a[i-1][i] = 1; if(i%6!=5) a[i+1][i] = 1; if(i>5) a[i-6][i] = 1; if(i<24) a[i+6][i] = 1; } gauss(); printf("PUZZLE #%d\n",++kase); for(int i=0;i<30;i++) { printf("%d",ans[i]); if(i%6==5) printf("\n"); else printf(" "); } } return 0; }

浙公网安备 33010602011771号