zoukankan      html  css  js  c++  java
  • poj 1753 Flip Game 高斯消元 异或方程组 求最值

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

    题意:给出一张4*4的图,表示16个方格的初始颜色的情况(白或黑),相邻方格操作的时候会相互影响,求最少的操作次数,使得每个方格都是白色或者都是黑色,如果不行输出Impossible。

    思路:和poj1222差不多,这题要求最值,所以要枚举自由变元的值。

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <cmath>
      5 using namespace std;
      6 #define maxn 5
      7 char mp[maxn][maxn];
      8 int a[maxn*maxn][maxn*maxn];
      9 int x[maxn*maxn];
     10 int free_x[maxn*maxn];
     11 int free_num;
     12 int mj_ans;
     13 #define inf 0x3f3f3f3f
     14 void init()
     15 {
     16     memset(a, 0, sizeof(a));
     17     for(int i = 0; i < 4; i++)
     18     {
     19         for(int j = 0; j < 4; j++)
     20         {
     21             int pos = i*4+j;
     22             a[pos][pos] = 1;
     23             if(i > 0) a[pos][(i-1)*4+j] = 1;
     24             if(i < 3) a[pos][(i+1)*4+j] = 1;
     25             if(j > 0) a[pos][i*4+j-1] = 1;
     26             if(j < 3) a[pos][i*4+j+1] = 1;
     27         }
     28     }
     29 }
     30 int Gauss(int n, int m)
     31 {
     32     memset(x, 0, sizeof(x));
     33     int r, c;
     34     free_num = 0;
     35     for(r = 0, c = 0; r < n && c < m; r++, c++)
     36     {
     37         int max_r = r;
     38         for(int i = r+1; i < n; i++)
     39         {
     40             if(fabs(a[i][c]) > fabs(a[max_r][c])) max_r = i;
     41         }
     42         if(a[max_r][c] == 0) {r--; free_x[free_num++] = c; continue;}
     43         if(max_r != r)
     44         {
     45             for(int i = c; i < m+1; i++) swap(a[r][i], a[max_r][i]);
     46         }
     47         
     48         for(int i = r+1; i < n; i++)
     49         {
     50             if(a[i][c] == 0) continue;
     51             for(int j = c; j < m+1; j++)
     52             {
     53                 a[i][j] ^= a[r][j];
     54             }
     55         }
     56     }
     57     for(int i = r; i < n; i++)
     58     {
     59         if(a[i][c]) return -1;
     60     }
     61     if(r < m)
     62     {
     63         mj_ans = inf;
     64         int cnt = m-r;
     65         for(int i = 0; i < (1<<cnt); i++)
     66         {
     67             int sum = 0;
     68             for(int j = 0; j < cnt; j++)
     69             {
     70                 if(i&(1<<j)) {x[free_x[j]] = 1; sum++;}
     71                 else x[free_x[j]] = 0;
     72             }
     73             for(int j = m-1-cnt; j >= 0; j--)
     74             {
     75                 int pos;
     76                 for(pos = j; pos < m; pos++) if(a[j][pos]) break;
     77                 x[pos] = a[j][m];
     78                 for(int k = pos+1; k < m; k++)
     79                 {
     80                     x[pos] ^= (a[j][k] && x[k]);
     81                 }
     82                 if(x[pos]) sum++;
     83             }
     84             if(sum < mj_ans) mj_ans = sum;
     85         }
     86         return m-r;
     87     }
     88     for(int i = m-1; i >= 0; i--)
     89     {
     90         x[i] = a[i][m];
     91         for(int j = i+1; j < m; j++)
     92         {
     93             x[i] ^= (a[i][j] && x[j]);
     94         }
     95     }
     96     return 0;
     97 }
     98 int main() 
     99 {
    100     
    101     //freopen("in.txt", "r", stdin);
    102     while(~scanf("%s", mp[0]))
    103     {
    104         for(int i = 1; i < 4; i++) scanf("%s", mp[i]);
    105 
    106         init();
    107         for(int i = 0; i < 4; i++)
    108         {
    109             for(int j = 0; j < 4; j++)
    110             {
    111                 if(mp[i][j] == 'b') a[i*4+j][16] = 1; 
    112             }
    113         }
    114         int cnt = Gauss(16, 16);
    115         int sum1 = 0, sum2 = 0;
    116         if(cnt == -1) sum1 = inf;
    117         else if(cnt == 0)
    118         {
    119             for(int i = 0; i < 16; i++)
    120             {
    121                 if(x[i]) sum1++;
    122             }
    123         }
    124         else sum1 = mj_ans;
    125 
    126 
    127         init();
    128         for(int i = 0; i < 4; i++)
    129         {
    130             for(int j = 0; j < 4; j++)
    131             {
    132                 if(mp[i][j] == 'w') a[i*4+j][16] = 1;
    133             }
    134         }
    135         cnt = Gauss(16, 16);
    136         if(cnt == -1) sum2 = inf;
    137         else if(cnt == 0)
    138         {
    139             for(int i = 0; i < 16; i++)
    140             {
    141                 if(x[i]) sum2++;
    142             }
    143         }
    144         else sum2 = mj_ans;
    145 
    146         if(min(sum1, sum2) == inf) printf("Impossible
    ");
    147         else printf("%d
    ", min(sum1, sum2));
    148 
    149     }
    150     return 0;
    151 }
  • 相关阅读:
    _ 下划线 Underscores __init__
    Page not found (404) 不被Django的exception中间件捕捉 中间件
    从装修儿童房时的门锁说起
    欧拉定理 费马小定理的推广
    线性运算 非线性运算
    Optimistic concurrency control 死锁 悲观锁 乐观锁 自旋锁
    Avoiding Full Table Scans
    批量的单向的ssh 认证
    批量的单向的ssh 认证
    Corrupted MAC on input at /usr/local/perl/lib/site_perl/5.22.1/x86_64-linux/Net/SSH/Perl/Packet.pm l
  • 原文地址:https://www.cnblogs.com/titicia/p/5397084.html
Copyright © 2011-2022 走看看