poj1753_flipgame_枚举
题意:这个题类似poj2965,但是这个题翻转操作是:翻转单位(i,j)以及与(i,j)相邻的单位。目标也是要求翻转为全白或者全黑需要翻转的次数。
分析:
枚举第一行(即对第一行的方块进行翻转),16种可能性。
翻转第二行的方块,修改对应列的第一行的方块,使得第一行全黑/白。
翻转第三行的方块,修改对应列的第二行的方块,使得第二行全黑/白。
翻转第四行的方块,修改对应列的第三行的方块,使得第三行全黑/白。
最后查看第四行是否满足全黑/白。若不满足,则"Impossible"(只要有一种枚举不满足,其它的枚举也不满足,反之,只要有一种枚举满足,则所有的枚举都满足,因为同一个方块翻转两次,整体不变,猜测所有的可行解都是可以互相转换,并都始于全黑/白,终于全黑/白),否则继续下一次枚举。
代码:
View Code
1 #include <iostream> 2 #include <stdio.h> 3 #include <memory.h> 4 using namespace std; 5 6 int array[5][5],t[5][5]; 7 int bit[5]; 8 9 void Getbit(int i) 10 { 11 int t=4; 12 while(i!=0) 13 { 14 bit[t]=i%2; 15 i=i/2; 16 t--; 17 } 18 } 19 20 void flip(int i,int j) 21 { 22 array[i][j]=array[i][j]>0?0:1; 23 if(i-1>=1) 24 array[i-1][j]=array[i-1][j]>0?0:1; 25 if(i+1<=4) 26 array[i+1][j]=array[i+1][j]>0?0:1; 27 if(j-1>=1) 28 array[i][j-1]=array[i][j-1]>0?0:1; 29 if(j+1<=4) 30 array[i][j+1]=array[i][j+1]>0?0:1; 31 } 32 33 int main() 34 { 35 int i,j,sum,k; 36 int cnt,min,stand; 37 char ch; 38 for(i=1;i<=4;i++) 39 { 40 for(j=1;j<=4;j++) 41 { 42 scanf("%c",&ch); 43 if(ch=='w') 44 { 45 array[i][j]=1; 46 t[i][j]=1; 47 } 48 else 49 { 50 array[i][j]=0; 51 t[i][j]=0; 52 } 53 } 54 getchar(); 55 } 56 min=16; //1 57 for(k=0;k<16;k++) 58 { 59 cnt=0; 60 sum=0; 61 memset(bit,0,sizeof(bit)); 62 Getbit(k); 63 64 for(i=1;i<=4;i++) 65 { 66 if(bit[i]==1) 67 { 68 flip(1,i); //0 1 69 cnt++; 70 } 71 sum+=array[1][i]; //01 72 } 73 74 if(sum>2) stand=1; //如果第一行1比0多,那么最后都翻转成1.反之成立。 75 else stand=0; 76 77 for(i=1;i<=3;i++) 78 for(j=1;j<=4;j++) 79 { 80 if(array[i][j]!=stand) 81 { 82 flip(i+1,j); 83 cnt++; 84 } 85 } 86 87 for(i=1;i<=4;i++) 88 if(array[4][i]!=stand) 89 { 90 printf("Impossible\n"); 91 return 0; 92 } 93 if(cnt==0) 94 { 95 printf("0\n"); 96 return 0; 97 } 98 else 99 { 100 if(cnt<min) 101 min=cnt; 102 for(i=1;i<=4;i++) 103 for(j=1;j<=4;j++) 104 array[i][j]=t[i][j]; 105 } 106 } 107 printf("%d\n",min); 108 return 0; 109 }
tju oj2357