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 }
posted on 2012-07-24 16:28  Dev-T  阅读(1942)  评论(0编辑  收藏  举报