标签:
题意:给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("\n"); 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\n", 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\n"); 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\n", min(t, tt)); 142 } 143 return 0; 144 }
标签:
原文地址:http://www.cnblogs.com/Empress/p/4248083.html