高斯消元以poj1222为例
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高斯消元以poj1222为例相关的知识,希望对你有一定的参考价值。
【题目链接】
http://poj.org/problem?id=1222
【题目大意】
5*6的一个由灯组成的方阵 操作一个灯 周围的上下左右四个灯会发生相应变化 即由灭变亮 由亮变灭 问如何操作使灯全亮
【题解】
对于每个灯可以列出一个方程
Lk:表示第 k 个灯的初始终状态
ai:表示第 i 个开关是否对 Lk 有影响
xj:表示第 j 个开关的状态
L1 XOR a1 *x1 XOR a2*x2 XOR a3*x3 XOR …… XOR a29*x29 XOR a30x30 = 0
L2 XOR a1 *x1 XOR a2*x2 XOR a3*x3 XOR …… XOR a29*x29 XOR a30x30 = 0
……
L30 XOR a1 *x1 XOR a2*x2 XOR a3*x3 XOR …… XOR a29*x29 XOR a30x30 = 0
解上述异或方程组即可得到答案。
为了方便求解,可将上述方程组变形,两边同时异或Lk (由于0^a = a),得:
a1 *x1 XOR a2*x2 XOR a3*x3 XOR …… XOR a29*x29 XOR a30x30 = L1
a1 *x1 XOR a2*x2 XOR a3*x3 XOR …… XOR a29*x29 XOR a30x30 = L2
……
a1 *x1 XOR a2*x2 XOR a3*x3 XOR …… XOR a29*x29 XOR a30x30 = L30
【ac代码】
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 6 int a[35][35]; //增广矩阵 7 int x[35]; //线性方程组的解 8 int equ; //方程个数 9 int var; //变量个数 10 11 void init() 12 { 13 memset(x, 0, sizeof(x)); 14 memset(a, 0, sizeof(a)); 15 } 16 17 void Gauss() 18 { 19 int row, col, i, j; 20 row = col = 0; 21 22 while(row<equ && col<var) 23 { 24 for(i=row; i<equ; ++i) //选出row~equ行中第一个为1的那一行 25 { 26 if(a[i][col] != 0) break; 27 } 28 if(i != row) //两行交换 29 { 30 for(j=col;j<=var;++j) 31 { 32 swap(a[row][j], a[i][j]); 33 } 34 } 35 if(a[row][col]==0) //无法消元,继续下一个变量 36 { 37 ++col; 38 continue; 39 } 40 41 for(int i=row+1;i<equ;++i) //消元 42 { 43 if(a[i][col]==0) continue; 44 for(int j=col;j<=var;++j) 45 { 46 a[i][j] ^= a[row][j]; 47 } 48 } 49 ++row; 50 ++col; 51 } 52 53 for(i=var-1;i>=0;--i) //回代求解 54 { 55 x[i] = a[i][var]; 56 for(j=i+1;j<var;++j) 57 { 58 x[i] ^= (a[i][j]&&x[j]); //回代关键步骤 59 } 60 } 61 } 62 63 int main() 64 { 65 int t; 66 int num; 67 scanf("%d", &t); 68 for(int item=1; item<=t; ++item) 69 { 70 init(); 71 for(int i=0;i<30;++i) 72 { 73 scanf("%d", &a[i][30]); 74 } 75 76 for(int i=0;i<5;++i) //确定方程组的系数 77 { //a[i][j]的意义:第j个开关能否控制第i个灯 78 for(int j=0;j<6;++j) 79 { 80 int num = i*6+j; 81 a[num][num] = 1; 82 if(i>=1) 83 { 84 a[num-6][num] = 1; 85 } 86 if(i<=3) 87 { 88 a[num+6][num] = 1; 89 } 90 if(j-1 >= 0) 91 { 92 a[num-1][num] = 1; 93 } 94 if(j+1 <= 5) 95 { 96 a[num+1][num] = 1; 97 } 98 } 99 } 100 101 equ = 30; 102 var = 30; 103 104 Gauss(); 105 printf("PUZZLE #%d\n", item); 106 for(int i=0;i<30;++i) 107 { 108 if(i%6==5) //控制每行输出6个 109 { 110 printf("%d", x[i]); 111 printf("\n"); 112 } 113 else 114 { 115 printf("%d ", x[i]); 116 } 117 } 118 } 119 return 0; 120 }
【模板】:后续更新
以上是关于高斯消元以poj1222为例的主要内容,如果未能解决你的问题,请参考以下文章
POJ 1222 extended lights out 高斯消元 板子题
POJ 1222 EXTENDED LIGHTS OUT 高斯消元