http://poj.org/problem?id=1222
http://poj.org/problem?id=1830
http://poj.org/problem?id=1681
http://poj.org/problem?id=1753
http://poj.org/problem?id=3185
这几个题目都类似,都可以使用高斯消元来求解一个模2的01方程组来解决。
有时候需要枚举自由变元,有的是判断存不存在解
普通的问题。
肯定有唯一解。肯定枚举第一行去做,也可以使用高斯消元。
1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2013/8/17 18:25:42 4 File Name :F:\2013ACM练习\专题学习\高斯消元\POJ1222.cpp 5 ************************************************ */ 6 7 #include <stdio.h> 8 #include <string.h> 9 #include <iostream> 10 #include <algorithm> 11 #include <vector> 12 #include <queue> 13 #include <set> 14 #include <map> 15 #include <string> 16 #include <math.h> 17 #include <stdlib.h> 18 #include <time.h> 19 using namespace std; 20 21 //对2取模的01方程组 22 const int MAXN = 40; 23 //有equ个方程,var个变元。增广矩阵行数为equ,列数为var+1,分别为0到var 24 int equ,var; 25 int a[MAXN][MAXN]; //增广矩阵 26 int x[MAXN]; //解集 27 int free_x[MAXN];//用来存储自由变元(多解枚举自由变元可以使用) 28 int free_num;//自由变元的个数 29 30 //返回值为-1表示无解,为0是唯一解,否则返回自由变元个数 31 int Gauss() 32 { 33 int max_r,col,k; 34 free_num = 0; 35 for(k = 0, col = 0 ; k < equ && col < var ; k++, col++) 36 { 37 max_r = k; 38 for(int i = k+1;i < equ;i++) 39 { 40 if(abs(a[i][col]) > abs(a[max_r][col])) 41 max_r = i; 42 } 43 if(a[max_r][col] == 0) 44 { 45 k--; 46 free_x[free_num++] = col;//这个是自由变元 47 continue; 48 } 49 if(max_r != k) 50 { 51 for(int j = col; j < var+1; j++) 52 swap(a[k][j],a[max_r][j]); 53 } 54 for(int i = k+1;i < equ;i++) 55 { 56 if(a[i][col] != 0) 57 { 58 for(int j = col;j < var+1;j++) 59 a[i][j] ^= a[k][j]; 60 } 61 } 62 } 63 for(int i = k;i < equ;i++) 64 if(a[i][col] != 0) 65 return -1;//无解 66 if(k < var) return var-k;//自由变元个数 67 //唯一解,回代 68 for(int i = var-1; i >= 0;i--) 69 { 70 x[i] = a[i][var]; 71 for(int j = i+1;j < var;j++) 72 x[i] ^= (a[i][j] && x[j]); 73 } 74 return 0; 75 } 76 void init() 77 { 78 memset(a,0,sizeof(a)); 79 memset(x,0,sizeof(x)); 80 equ = 30; 81 var = 30; 82 for(int i = 0;i < 5;i++) 83 for(int j = 0;j < 6;j++) 84 { 85 int t = i*6+j; 86 a[t][t] = 1; 87 if(i > 0)a[(i-1)*6+j][t] = 1; 88 if(i < 4)a[(i+1)*6+j][t] = 1; 89 if(j > 0)a[i*6+j-1][t] = 1; 90 if(j < 5)a[i*6+j+1][t] = 1; 91 } 92 } 93 int main() 94 { 95 //freopen("in.txt","r",stdin); 96 //freopen("out.txt","w",stdout); 97 int T; 98 int iCase = 0; 99 scanf("%d",&T); 100 while(T--) 101 { 102 iCase++; 103 init(); 104 for(int i = 0;i < 30;i++) 105 scanf("%d",&a[i][30]); 106 Gauss(); 107 printf("PUZZLE #%d\n",iCase); 108 for(int i = 0;i < 5;i++) 109 { 110 for(int j = 0;j < 5;j++) 111 printf("%d ",x[i*6+j]); 112 printf("%d\n",x[i*6+5]); 113 } 114 } 115 return 0; 116 }