zoukankan      html  css  js  c++  java
  • [Gauss]POJ1753 Flip Game

    题意:给4×4的棋盘的初始状态,b代表黑,w代表白。

    要求变成全黑或者全白 最少需要几步。

    简单的做法 可以暴搜 状压bfs 不再赘述 

    主要学习Gauss做法

    同样是01方程组 用异或解

    注意全黑或全白都可以

    即 bbbb        wwww

        bbbb        wwww

      bbbb        wwww

      bbbb        wwww      这两种的步数步数都是0.

    因此我的做法是 列两个方程组分别求最小步数,再取最小值

      1 int a[300][300];  // 增广矩阵
      2 int b[300][300];
      3 int x[300];  //
      4 int free_x[300]; // 标记是否为自由未知量
      5 
      6 int n;
      7 void debug()
      8 {
      9     for(int i0=0;i0<n*n;i0++)
     10     {
     11         for(int j0=0;j0<n*n;j0++)
     12             printf("%d ", a[i0][j0]);
     13         printf("
    ");
     14     }
     15 }
     16 
     17 int Gauss(int n, int m) // n个方程 m个未知数 即 n行m+1列
     18 {
     19     //转换为阶梯形式
     20     int col=0, k, num=0;
     21     for(k=0;k<n && col<m;k++, col++)
     22     {//枚举行
     23         int max_r=k;
     24         for(int i=k+1;i<n;i++)//找到第col列元素绝对值最大的那行与第k行交换
     25             if(abs(a[i][col])>abs(a[max_r][col]))
     26                 max_r=i;
     27         if(max_r!=k)// 与第k行交换
     28             for(int j=col;j<m+1;j++)
     29                 swap(a[k][j], a[max_r][j]);
     30         if(!a[k][col])// 说明该col列第k行以下全是0了
     31         {
     32             k--;
     33             free_x[num++]=col;
     34             continue;
     35         }
     36         for(int i=k+1;i<n;i++)// 枚举要删除的行
     37             if(a[i][col])
     38                 for(int j=col;j<m+1;j++)
     39                     a[i][j]^=a[k][j];
     40     }
     41 
     42 //    debug();
     43 //    printf("%d %d
    ", col, k);
     44 
     45     for(int i=k;i<n;i++)
     46         if(a[i][col])
     47             return -1; // 无解
     48 
     49 //    if(k<m)   //m-k为自由未知量个数
     50 //    {
     51         int stat=1<<(m-k);
     52         int ans=INT_MAX;
     53         for(int i=0;i<stat;i++)
     54         {
     55             int cnt=0;
     56             for(int j=0;j<m-k;j++)
     57                 if(i&(1<<j))
     58                 {
     59                     x[free_x[j]]=1;
     60                     cnt++;
     61                 }
     62                 else
     63                     x[free_x[j]]=0;
     64             for(int j=k-1;j>=0;j--)
     65             {
     66                 int tmp;
     67                 for(tmp=j;tmp<m;tmp++)
     68                     if(a[j][tmp])
     69                         break;
     70                 x[tmp]=a[j][m];
     71                 for(int l=tmp+1;l<m;l++)
     72                     if(a[j][l])
     73                         x[tmp]^=x[l];
     74                 cnt+=x[tmp];
     75             }
     76             if(cnt<ans)
     77                 ans=cnt;
     78         }
     79         return ans;
     80 //    }
     81 
     82 //    //  唯一解 回代
     83 //    for(int i=m-1;i>=0;i--)
     84 //    {
     85 //        x[i]=a[i][m];
     86 //        for(int j=i+1;j<m;j++)
     87 //            x[i]^=(a[i][j] && x[j]);
     88 //    }
     89 //    int ans=0;
     90 //    for(int i=0;i<n*n;i++)
     91 //        ans+=x[i];
     92 //    return ans;
     93 }
     94 
     95 
     96 void init()
     97 {
     98     n=4;
     99     memset(a, 0, sizeof(a));
    100     memset(x, 0, sizeof(x));
    101     for(int i=0;i<n;i++)
    102         for(int j=0;j<n;j++)
    103         {
    104             int t=i*n+j;
    105             a[t][t]=1;
    106             if(i>0)
    107                 a[(i-1)*n+j][t]=1;
    108             if(i<n-1)
    109                 a[(i+1)*n+j][t]=1;
    110             if(j>0)
    111                 a[i*n+j-1][t]=1;
    112             if(j<n-1)
    113                 a[i*n+j+1][t]=1;
    114         }
    115 }
    116 
    117 int main()
    118 {
    119     char ch;
    120     while(cin>>ch)
    121     {
    122         init();
    123         a[0][16]=(ch=='b');
    124         b[0][16]=(ch=='w');
    125         for(int i=1;i<16;i++)
    126         {
    127             cin>>ch;
    128             a[i][n*n]=(ch=='b');
    129             b[i][n*n]=(ch=='w');
    130         }
    131         int t=Gauss(n*n, n*n);
    132         if(t==-1)
    133         {
    134             printf("Impossible
    ");
    135             continue ;
    136         }
    137         init();
    138         for(int i=0;i<16;i++)
    139             a[i][16]=b[i][16];
    140         int tt=Gauss(n*n, n*n);
    141         printf("%d
    ", min(t, tt));
    142     }
    143     return 0;
    144 }
    POJ 1753
  • 相关阅读:
    3.1 history跳转页面产生跨域问题
    2021年6月7日 团队冲刺第二阶段04
    2021年6月6日 团队冲刺第二阶段03
    2021年6月5日 团队冲刺第二阶段02
    2021年6月4日 团队冲刺第二阶段01
    2021年6月3日
    2021年6月2日
    2021年6月1日
    2021年5月31日
    2021年5月30日
  • 原文地址:https://www.cnblogs.com/Empress/p/4248083.html
Copyright © 2011-2022 走看看