POJ 1222(高斯消元法)
这是我第一道用gauss消元做的题,其实高斯消元的原理,我们很早以前就已经用过,就是用已知方程变形后相加减,逐步消去至一个未知数的方法,线性代数上也有讲过。
这题其实开始的时候,一点思路都没有。。。线性代数真心水啊。这个gauss我还是照着伪代码写的。
这题分析如下:未知数共30个,因为30个灯的状态我们都必须要确定下来才能解决这道题。
比如说(1,1)这个灯的最终状态将由(1,1),(1,2),(2,1)这三个灯的状态决定这样就可以列出一个方程:
(l(1,1)+x(1,1)+x(1,2)+0*x(1,3)+...+x(2,1)+...)%2=0(l表示给出的初始状态的矩阵,x表示最终需要求的开关矩阵),再比如说对于(1,2)这个灯的状态又可列出一个方程:
(l(1,2)+x(1,1)+x(1,2)+x(1,3)+...+x(2,2)+...)%2=0这样对于30个位置我们可以列出30个方程(不相关),共有30个未知数,故方程一定有唯一解。
View Code
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<cmath> 6 #define EPS 1e-8 7 #define MAXN 30 8 #define MAXM 31 9 using namespace std; 10 int matrix[MAXN][MAXM] = {0}; 11 int puzzle[5][6] = {0}; 12 const int dir[4][2] = {0,1,1,0,0,-1,-1,0}; 13 14 void gauss(int n, int m) 15 { 16 int i(0),j(0); 17 while (i<n && j<m) { 18 int maxi = i; 19 for (int k(i+1); k<n; ++k) { 20 if (matrix[k][j] == 1) { 21 maxi = k; 22 break; 23 } 24 } 25 26 if (matrix[maxi][j] != 0) { 27 if (maxi != i) { 28 for (int k(0); k<m; ++k) { 29 swap(matrix[maxi][k],matrix[i][k]); 30 } 31 } 32 33 for (int u(0); u<n; ++u) { 34 if (i != u && matrix[u][j]) { 35 for (int k(j); k<m; ++k) { 36 matrix[u][k] = matrix[u][k]^matrix[i][k]; 37 } 38 } 39 } 40 ++i; 41 } 42 ++j; 43 } 44 } 45 46 bool law(int i, int j) 47 { 48 return i>=0 && i<5 && j>=0 && j<6; 49 } 50 51 int main() 52 { 53 int t; 54 scanf("%d",&t); 55 for (int i(1); i<=t; ++i) { 56 memset(matrix,0,sizeof(matrix)); 57 memset(puzzle,0,sizeof(puzzle)); 58 cout<<"PUZZLE "<<"#"<<i<<endl; 59 for (int j(0); j<5; ++j) { 60 for (int k(0); k<6; ++k) { 61 scanf("%d",&puzzle[j][k]); 62 matrix[j*6+k][30] = puzzle[j][k]; 63 } 64 } 65 66 for (int j(0); j<5; ++j) { 67 for (int k(0); k<6; ++k) { 68 matrix[j*6+k][j*6+k] = 1; 69 for (int l(0); l<4; ++l) { 70 int nowj = j + dir[l][0]; 71 int nowk = k + dir[l][1]; 72 if (law(nowj,nowk)) { 73 matrix[j*6+k][nowj*6+nowk] = 1; 74 } 75 } 76 } 77 } 78 gauss(MAXN,MAXM); 79 for (int j(0); j<5; ++j) { 80 for (int k(0); k<6; ++k) { 81 puzzle[j][k] = matrix[j*6+k][30]; 82 cout<<puzzle[j][k]<<" "; 83 } 84 cout<<endl; 85 } 86 } 87 return 0; 88 }