题目大意:一个冰箱上面有16个按钮,“+”代表按钮为关,“-”代表按钮为开。 当16个按钮都为开的时候冰箱才能打开。
游戏规则:你可以改变矩阵里任意位置(i,j)的状态,但是第i行和第j列的所有状态都须改变。然后问你最少需要改变多少次状态可以打开冰箱。
解题思路: 枚举+DFS(类似于poj1753)
类似于poj1753,枚举16种可能性(可能只需改变一个按钮都可以使所有按钮都打开、可能只需改变两个按钮都可以使所有按钮都打开,可能只需改变三个按钮都可以使所有按钮都打开.......可能只需改变十六个按钮都可以使所有按钮都打开) 。然后深搜每一种可能性,找到每一种可能性按钮的所有状态,看是否能打开冰箱。
还有一点需要输出 最小步数 改变的按钮位置。这时可以定义一个b[4][4],初始化为0,改变的时候赋值为1。最后输出b为1的位置即可。
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 int a[4][4]; 7 int b[4][4]; 8 int flag; 9 int judge() 10 { 11 int cnt=0; 12 int i,j; 13 for(i=0;i<4;i++) 14 for(j=0;j<4;j++) 15 if (a[i][j]) 16 cnt++; 17 if (cnt==16) 18 return 1; 19 return 0; 20 } 21 void change(int i,int j) 22 { 23 int k; 24 a[i][j]^=1; 25 for(k=0;k<4;k++) 26 a[i][k]^=1; 27 for(k=0;k<4;k++) 28 a[k][j]^=1; 29 } 30 void dfs(int j,int now,int sum) 31 { 32 int i; 33 if (now==sum) 34 { 35 flag=judge(); 36 return ; 37 } 38 for(i=j+1;i<16;i++) 39 { 40 change(i/4,i%4); 41 b[i/4][i%4]=1; 42 dfs(i,now+1,sum); 43 if (flag) 44 return ; 45 change(i/4,i%4); 46 b[i/4][i%4]=0; 47 } 48 } 49 int main() 50 { 51 int i,j; 52 char c; 53 memset(a,0,sizeof(a)); 54 memset(b,0,sizeof(b)); 55 for(i=0;i<4;i++) 56 { 57 for(j=0;j<4;j++) 58 { 59 scanf("%c",&c); 60 if(c=='+') 61 a[i][j]=0; 62 else 63 a[i][j]=1; 64 } 65 getchar(); 66 } 67 int sum=0; 68 flag=0; 69 for(i=0;i<16;i++) 70 { 71 dfs(-1,0,++sum); 72 if (flag) 73 break; 74 } 75 printf("%d ",sum); 76 for(i=0;i<4;i++) 77 for(j=0;j<4;j++) 78 { 79 if (b[i][j]) 80 printf("%d %d ",i+1,j+1); 81 } 82 return 0; 83 }