POJ1753 Flip Game【高斯消元法】
来源:互联网 发布:淘宝bug 编辑:程序博客网 时间:2024/05/22 11:54
题目链接:
http://poj.org/problem?id=1753
题目大意:
有一个 4*4 的棋盘,棋盘上有黑色和白色的格子,每一次你可以翻其中的一个格子,这
个格子(x,y)如果被翻,那么对应位置为(x-1,y)、(x+1,y)、(x,y-1)、(x,y+1)
格子的颜色会变成相对的颜色,现在求将棋盘全部翻为白色格子或者是黑色格子用的最
少的步数是多少?如果无法把所有格子都翻为白色或者是黑色,那么输出 "Impossible"。
解题思路:
和 POJ1222 一样,一个格子变化最多改变 5 个格子,其中格子改变为 1,格子不改变
为 0,则每个位置上的格子向量中最多有 5 项为 1,其余为 0。这样 16 个位置的开
关向量构成一个 16*16 的格子矩阵 A[][]。用 A[][] 第16列 (即A[][N]) 的 16*1 向量来存
储改变结果,A[i][N] 来表示第 i 个开关是否改变。然后用高斯消元求解。
无解输出"Impossible",有唯一解则求出解集中 1 的和。有无穷解则枚举自由变元来找
到最优解。
因为可以全部转为白色或是黑色,所以需要做两次高斯消元。
AC代码:
#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<cmath>using namespace std;const int MAXN = 300;const int INF = 0xffffff0;int Equ,Var;int A[MAXN][MAXN];int X[MAXN];bool FreeX[MAXN];int FreeNum;int FreeOnly[MAXN];void Debug(){ for(int i = 0; i < Equ; ++i) { for(int j = 0; j < Var+1; ++j) cout << A[i][j] << ' '; cout << endl; }}int GCD(int a,int b){ if(b == 0) return a; return GCD(b,a%b);}int LCM(int a,int b){ return a / GCD(a,b) * b;}int Gauss(){ int i,j,k; int MaxRow; int col; int Lcm; int ta,tb; int temp; int FreeXNum = 0; int FreeIndex; col = 0; for(int i = 0; i <= Var; ++i) { X[i] = 0; FreeX[i] = true; } for(k = 0; k < Equ && col < Var; ++k,++col) { MaxRow = k; for(i = k+1; i < Equ; ++i) { if(abs(A[i][col]) > abs(A[MaxRow][col])) MaxRow = i; } if(MaxRow != k) { for(j = k; j < Var+1; ++j) swap(A[k][j],A[MaxRow][j]); } if(A[k][col] == 0) { k--; FreeOnly[FreeXNum++] = col; continue; } for(i = k+1; i < Equ; ++i) { if(A[i][col]) { Lcm = LCM(abs(A[i][col]),abs(A[k][col])); ta = Lcm / abs(A[i][col]); tb = Lcm / abs(A[k][col]); if(A[i][col] * A[k][col] < 0) tb = -tb; for(j = col; j < Var+1; ++j) A[i][j] = (A[i][j]*ta%2 - A[k][j]*tb%2 + 2) % 2; } } } for(i = k; i < Equ; ++i) { if(A[i][col]) return -1; } if(k < Var) {// for(i = k-1; i >= 0; --i)// {// FreeXNum = 0;// for(j = 0; j < Var; ++j)// {// if(A[i][j] && FreeX[j])// {// FreeXNum++;// FreeIndex = j;// }// }// if(FreeXNum > 1)// continue;// temp = A[i][Var]%2;// for(j = 0; j < Var; ++j)// {// if(A[i][j] && j != FreeIndex)// temp = (temp - A[i][j]*X[j]%2 + 2) % 2;// }// X[FreeIndex] = temp / A[i][FreeIndex] % 2;// FreeX[FreeIndex] = 0;// }// j = 0;// for(i = 0; i < Var; ++i)// {// if(FreeX[i])// FreeOnly[j++] = i;// } return Var - k; } for(i = Var-1; i >= 0; --i) { temp = A[i][Var] % 2; for(j = i+1; j < Var; ++j) { if(A[i][j]) temp = (temp - A[i][j]*X[j]%2 + 2) % 2; } if(temp % A[i][i] != 0) return -2; X[i] = temp / A[i][i] % 2; } return 0;}int Solve(){ FreeNum = Gauss(); if(FreeNum == -1) return INF; else if(FreeNum == 0) { int Ans = 0; for(int i = 0; i < Var; ++i) Ans += X[i]; return Ans; } else { int Ans = INF; for(int i = 0; i < (1 << FreeNum); ++i) { int Cnt = 0; for(int j = 0; j < FreeNum; ++j) { if(i & (1<<j)) { X[FreeOnly[j]] = 1; Cnt++; } else X[FreeOnly[j]] = 0; } for(int j = Var-FreeNum-1; j >= 0; --j) { int idx; for(idx = j; idx < Var; ++idx) if(A[j][idx]) break; X[idx] = A[j][Var]; for(int k = idx+1; k < Var; ++k) { if(A[j][k]) X[idx] = (X[idx] - X[k] + 2)%2; } Cnt += X[idx]; } Ans = min(Ans,Cnt); } return Ans; }}void Init(int N){ memset(A,0,sizeof(A)); memset(X,0,sizeof(X)); Equ = Var = N*N; for(int i = 0; i < N; ++i) { for(int j = 0; j < N; ++j) { A[i*N+j][i*N+j] = 1; if(i > 0) A[(i-1)*N+j][i*N+j] = 1; if(i < N-1) A[(i+1)*N+j][i*N+j] = 1; if(j > 0) A[i*N+j-1][i*N+j] = 1; if(j < N-1) A[i*N+j+1][i*N+j] = 1; } }}char s[10][10];int main(){ int N = 4; for(int i = 0; i < 4; ++i) scanf("%s",s[i]); Init(N); for(int i = 0; i < 4; ++i) { for(int j = 0; j < 4; ++j) { if(s[i][j] == 'b') A[i*4+j][16] = 1; else A[i*4+j][16] = 0; } } int Ans1 = Solve(); Init(N); for(int i = 0; i < 4; ++i) { for(int j = 0; j < 4; ++j) { if(s[i][j] == 'b') A[i*4+j][16] = 0; else A[i*4+j][16] = 1; } } int Ans2 = Solve(); if(Ans1 == INF && Ans2 == INF) printf("Impossible\n"); else printf("%d\n",min(Ans1,Ans2)); return 0;}
0 0
- POJ1753 Flip Game【高斯消元法】
- poj1753 Flip Game
- poj1753 Flip Game
- poj1753 Flip Game
- poj1753 flip game题解
- POJ1753 Flip Game
- POJ1753-Flip Game
- poj1753 - Flip Game
- POJ1753 Flip Game
- poj1753 Flip Game
- POJ1753 Flip Game
- poj1753:Flip Game
- POJ1753 Flip Game【DFS】
- poj1753-Flip Game
- poj1753 Flip Game 广搜哈希
- poj1753--Flip Game
- poj1753 Flip Game
- POJ1753:Flip Game
- word转pdf还有什么好的方法
- 设定字符串字符的颜色
- iOS界面设计切图小结
- Uva 11582 Colossal Fibonacci Numbers! 快速幂,斐波那契
- LeetCode_OJ【15】3Sum
- POJ1753 Flip Game【高斯消元法】
- C++全局函数与类成员函数的区别和相互转化
- jQuery与MooTools库的一些比对
- Java NIO内存映射---上G大文件处理
- dell 功能快捷键切换
- UIImageView和UIButton的区别
- @SuppressWarnings注解
- %02f前面却出现很多6个f
- linux下为php5.5安装apc失败解决办法