[HIHO1196]高斯消元·二(高斯消元枚举自由变元)

Posted tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[HIHO1196]高斯消元·二(高斯消元枚举自由变元)相关的知识,希望对你有一定的参考价值。

题目链接:http://hihocoder.com/problemset/problem/1196

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 
  4 typedef pair<int, int> pii;
  5 const int maxn = 230;
  6 int equ, var;
  7 int a[maxn][maxn];
  8 int x[maxn];
  9 int free_x[maxn];
 10 int free_num;
 11 int ret;
 12 
 13 int gauss() {
 14     int max_r, col, k;
 15     free_num = 0;
 16     for(k = 0, col = 0; k < equ && col < var; k++, col++) {
 17         max_r = k;
 18         for(int i = k + 1; i < equ; i++) {
 19             if(abs(a[i][col]) > abs(a[max_r][col]))
 20                 max_r = i;
 21         }
 22         if(a[max_r][col] == 0) {
 23             k--;
 24             free_x[free_num++] = col;
 25             continue;
 26         }
 27         if(max_r != k) {
 28             for(int j = col; j < var + 1; j++)
 29                 swap(a[k][j], a[max_r][j]);
 30         }
 31         for(int i = k + 1; i < equ; i++) {
 32             if(a[i][col] != 0) {
 33                 for(int j = col; j < var + 1; j++) {
 34                     a[i][j] ^= a[k][j];
 35                 }
 36             }
 37         }
 38     }
 39     for(int i = k; i < equ; i++) {
 40         if(a[i][col] != 0)
 41             return -1;
 42     }
 43     if(k < var) return var - k;
 44     for(int i = var - 1; i >= 0; i--) {
 45         x[i] = a[i][var];
 46         for(int j = i + 1; j < var; j++) {
 47             x[i] ^= (a[i][j] & x[j]);
 48         }
 49     }
 50     return 0;
 51 }
 52 
 53 char G[maxn][maxn];
 54 int n, m;
 55 
 56 int main() {
 57     // freopen("in", "r", stdin);
 58     m = 5, n = 6;
 59     var = equ = 30;
 60     ret = 0;
 61     memset(a, 0, sizeof(a));
 62     for(int i = 0; i < n; i++) scanf("%s", G[i]);
 63     for(int i = 0; i < m; i++) {
 64         for(int j = 0; j < n; j++) {
 65             if(G[i][j] == 0) a[i*n+j][var] = 1;
 66             else a[i*n+j][var] = 0;
 67         }
 68     }
 69     for(int i = 0; i < 30; i++) {
 70         a[i][i] = 1;
 71         if(i % 6 != 0) a[i-1][i] = 1;
 72         if(i % 6 != 5) a[i+1][i] = 1;
 73         if(i > 5) a[i-6][i] = 1;
 74         if(i < 24) a[i+6][i] = 1;
 75     }
 76     int v = gauss();
 77     if(v == -1) ret = -1;
 78     else if(v != 0) {
 79         ret = maxn;
 80         int tot = 1 << v;
 81         for(int i = 0; i < tot; i++) {
 82             int cnt = 0;
 83             for(int j = 0; j < v; j++) {
 84                 if(i&(1<<j)) {
 85                     x[free_x[j]] = 1;
 86                     cnt++;
 87                 }
 88                 else x[free_x[j]] = 0;
 89             }
 90             for(int j = var - v - 1; j >= 0; j--) {
 91                 int idx;
 92                 for(idx = j; idx < var; idx++) {
 93                     if(a[j][idx]) break;
 94                 }
 95                 x[idx] = a[j][var];
 96                 for(int l = idx + 1; l < var; l++) {
 97                     if(a[j][l]) x[idx] ^= x[l];
 98                 }
 99                 cnt += x[idx];
100             }
101             ret = min(ret, cnt);
102         }
103     }
104     else for(int i = 0; i < var; i++) ret += x[i];
105     printf("%d\n", ret);
106     vector<pii> va;
107     for(int i = 0; i < 30; i++) {
108         if(x[i]) {
109             int pos = i + 1;
110             int r = 1, c = 0;
111             while(pos > 6) {
112                 pos -= 6;
113                 r++;
114             }
115             c += pos;
116             va.push_back(pii(r, c));
117         }
118     }
119     sort(va.begin(), va.end());
120     for(int i = 0; i < va.size(); i++) {
121         printf("%d %d\n", va[i].first, va[i].second);
122     }
123     return 0;
124 }

 

以上是关于[HIHO1196]高斯消元·二(高斯消元枚举自由变元)的主要内容,如果未能解决你的问题,请参考以下文章

hihoCoder#1196 : 高斯消元·二(开关灯问题)

hihoCoder1196 (高斯消元)

hihoCoder #1195 : 高斯消元·一

高斯消元学习

线性方程直接求法——高斯消元法(一)

高斯消元法