zoukankan      html  css  js  c++  java
  • [POJ1753]Flip Game(异或方程组,高斯消元,枚举自由变量)

    题目链接:http://poj.org/problem?id=1753

    题意:同上。

    这回翻来翻去要考虑自由变元了,假设返回了自由变元数量,则需要枚举自由变元。

      1 /*
      2 ━━━━━┒ギリギリ♂ eye!
      3 ┓┏┓┏┓┃キリキリ♂ mind!
      4 ┛┗┛┗┛┃\○/
      5 ┓┏┓┏┓┃ /
      6 ┛┗┛┗┛┃ノ)
      7 ┓┏┓┏┓┃
      8 ┛┗┛┗┛┃
      9 ┓┏┓┏┓┃
     10 ┛┗┛┗┛┃
     11 ┓┏┓┏┓┃
     12 ┛┗┛┗┛┃
     13 ┓┏┓┏┓┃
     14 ┃┃┃┃┃┃
     15 ┻┻┻┻┻┻
     16 */
     17 #include <algorithm>
     18 #include <iostream>
     19 #include <iomanip>
     20 #include <cstring>
     21 #include <climits>
     22 #include <complex>
     23 #include <cassert>
     24 #include <cstdio>
     25 #include <bitset>
     26 #include <vector>
     27 #include <deque>
     28 #include <queue>
     29 #include <stack>
     30 #include <ctime>
     31 #include <set>
     32 #include <map>
     33 #include <cmath>
     34 using namespace std;
     35 
     36 const int maxn = 230;
     37 int equ, var;
     38 int a[maxn][maxn];
     39 int x[maxn];
     40 int free_x[maxn];
     41 int free_num;
     42 int ret1, ret2;
     43 
     44 int gauss() {
     45     int max_r, col, k;
     46     free_num = 0;
     47     for(k = 0, col = 0; k < equ && col < var; k++, col++) {
     48         max_r = k;
     49         for(int i = k + 1; i < equ; i++) {
     50             if(abs(a[i][col]) > abs(a[max_r][col]))
     51                 max_r = i;
     52         }
     53         if(a[max_r][col] == 0) {
     54             k--;
     55             free_x[free_num++] = col;
     56             continue;
     57         }
     58         if(max_r != k) {
     59             for(int j = col; j < var + 1; j++)
     60                 swap(a[k][j], a[max_r][j]);
     61         }
     62         for(int i = k + 1; i < equ; i++) {
     63             if(a[i][col] != 0) {
     64                 for(int j = col; j < var + 1; j++) {
     65                     a[i][j] ^= a[k][j];
     66                 }
     67             }
     68         }
     69     }
     70     for(int i = k; i < equ; i++) {
     71         if(a[i][col] != 0)
     72             return -1;
     73     }
     74     if(k < var) return var - k;
     75     for(int i = var - 1; i >= 0; i--) {
     76         x[i] = a[i][var];
     77         for(int j = i + 1; j < var; j++) {
     78             x[i] ^= (a[i][j] & x[j]);
     79         }
     80     }
     81     return 0;
     82 }
     83 
     84 char G[maxn][maxn];
     85 int n;
     86 
     87 int main() {
     88     // freopen("in", "r", stdin);
     89     n = 4;
     90     var = equ = 16;
     91     ret1 = ret2 = 0;
     92     memset(a, 0, sizeof(a));
     93     for(int i = 0; i < n; i++) scanf("%s", G[i]);
     94     for(int i = 0; i < n; i++) {
     95         for(int j = 0; j < n; j++) {
     96             if(G[i][j] == 'b') a[i*n+j][var] = 1;
     97             else a[i*n+j][var] = 0;
     98         }
     99     }
    100     for(int i = 0; i < n; i++) {
    101         for(int j = 0; j < n; j++) {
    102             int q = i * n + j;
    103             a[q][q] = 1;
    104             if(i > 0) a[(i-1)*n+j][q] = 1;
    105             if(i < n - 1) a[(i+1)*n+j][q] = 1;
    106             if(j > 0) a[i*n+j-1][q] = 1;
    107             if(j < n - 1) a[i*n+j+1][q] = 1;
    108         }
    109     }
    110     int v1 = gauss();
    111     if(v1 == -1) ret1 = -1;
    112     else if(v1 != 0) {
    113         ret1 = maxn;
    114         int tot = 1 << v1;
    115         for(int i = 0; i < tot; i++) {
    116             int cnt = 0;
    117             for(int j = 0; j < v1; j++) {
    118                 if(i&(1<<j)) {
    119                     x[free_x[j]] = 1;
    120                     cnt++;
    121                 }
    122                 else x[free_x[j]] = 0;
    123             }
    124             for(int j = var - v1 - 1; j >= 0; j--) {
    125                 int idx;
    126                 for(idx = j; idx < var; idx++) {
    127                     if(a[j][idx]) break;
    128                 }
    129                 x[idx] = a[j][var];
    130                 for(int l = idx + 1; l < var; l++) {
    131                     if(a[j][l]) x[idx] ^= x[l];
    132                 }
    133                 cnt += x[idx];
    134             }
    135             ret1 = min(ret1, cnt);
    136         }
    137     }
    138     else for(int i = 0; i < var; i++) ret1 += x[i];
    139 
    140     memset(a, 0, sizeof(a));
    141     for(int i = 0; i < n; i++) {
    142         for(int j = 0; j < n; j++) {
    143             if(G[i][j] == 'w') a[i*n+j][var] = 1;
    144             else a[i*n+j][var] = 0;
    145         }
    146     }
    147     for(int i = 0; i < n; i++) {
    148         for(int j = 0; j < n; j++) {
    149             int q = i * n + j;
    150             a[q][q] = 1;
    151             if(i > 0) a[(i-1)*n+j][q] = 1;
    152             if(i < n - 1) a[(i+1)*n+j][q] = 1;
    153             if(j > 0) a[i*n+j-1][q] = 1;
    154             if(j < n - 1) a[i*n+j+1][q] = 1;
    155         }
    156     }
    157 
    158     int v2 = gauss();
    159     if(v2 == -1) ret2 = -1;
    160     else if(v2 != 0) {
    161         ret2 = maxn;
    162         int tot = 1 << v2;
    163         for(int i = 0; i < tot; i++) {
    164             int cnt = 0;
    165             for(int j = 0; j < v2; j++) {
    166                 if(i&(1<<j)) {
    167                     x[free_x[j]] = 1;
    168                     cnt++;
    169                 }
    170                 else x[free_x[j]] = 0;
    171             }
    172             for(int j = var - v2 - 1; j >= 0; j--) {
    173                 int idx;
    174                 for(idx = j; idx < var; idx++) {
    175                     if(a[j][idx]) break;
    176                 }
    177                 x[idx] = a[j][var];
    178                 for(int l = idx + 1; l < var; l++) {
    179                     if(a[j][l]) x[idx] ^= x[l];
    180                 }
    181                 cnt += x[idx];
    182             }
    183             ret2 = min(ret2, cnt);
    184         }
    185     }
    186     else for(int i = 0; i < var; i++) ret2 += x[i];
    187     if(ret1==-1&&ret2==-1) puts("Impossible");
    188     else if(v1==-1) printf("%d
    ", ret2);
    189     else if(ret2==-1) printf("%d
    ", ret1);
    190     else printf("%d
    ", min(ret1, ret2));
    191     return 0;
    192 }
  • 相关阅读:
    hdu 1823 Luck and Love 二维线段树
    UVA 12299 RMQ with Shifts 线段树
    HDU 4578 Transformation 线段树
    FZU 2105 Digits Count 线段树
    UVA 1513 Movie collection 树状数组
    UVA 1292 Strategic game 树形DP
    【ACM】hdu_zs2_1003_Problem C_201308031012
    qsort快速排序
    【ACM】nyoj_7_街区最短路径问题_201308051737
    【ACM】nyoj_540_奇怪的排序_201308050951
  • 原文地址:https://www.cnblogs.com/kirai/p/6139292.html
Copyright © 2011-2022 走看看