• [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 }
  • 相关阅读:
    《人月神话》阅读笔记02
    学习进度条-4
    课堂作业3
    MySql 8.0及对应驱动包匹配注意点
    关于Ubuntu中Could not get lock /var/lib/dpkg/lock解决方案
    STM32之ADC配置,ADC_Mode模式理解
    STM32串口中断的方式发送
    RTC 与RCC 之间的关系
    stm32 MDK5软件仿真之查看io口输出
    STM32 PWM学习
  • 原文地址:https://www.cnblogs.com/kirai/p/6139292.html
Copyright © 2020-2023  润新知