• 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 }
  • 相关阅读:
    C# 中数组、ArrayList、List<T> 区别
    启动SourceNavigator出错(问题解决)
    (转)SlickEdit软件使用
    ubuntu操作记录
    ubuntu下安装Source Insight
    Android中对于没有Looper的类,要使用Toast的问题
    (转)ubuntu下安装source navigator
    (转)深入理解之 Android Handler(相当好!!!)
    Git常用命令及思维导图
    (转)android的消息处理机制(图+源码分析)——Looper,Handler,Message
  • 原文地址:https://www.cnblogs.com/titicia/p/5397084.html
Copyright © 2020-2023  润新知