高斯消元以poj1222為例
阿新 • • 發佈:2017-08-27
tin 組成 sub ac代碼 題目 iostream tdi pre 變亮
【題目鏈接】
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)); 14memset(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為例