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方程组来解决。

有时候需要枚举自由变元,有的是判断存不存在解

 

POJ 1222 EXTENDED LIGHTS OUT

普通的问题。

肯定有唯一解。肯定枚举第一行去做,也可以使用高斯消元。

  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 }
View Code

相关文章: