POJ_2965_The Pilots Brothers' refrigerator(Enum枚举)
题意:冰箱门上有16个把手,每一个把手有2种状态,只有当16个把手都是开的状态时冰箱门才能打开
"—"代表开,每次操作你必须把当前位置的列和行的把手状态都反转。输入把手的状态,让你输出打开冰箱门需要的操作步数,和翻转的坐标。
http://poj.org/problem?id=2965
/*
本题和POJ_1753http://www.cnblogs.com/liun1994/articles/3247449.html
差不多,用的方法也是DFS但是本题的反转操作需要
本行本列全部反转,稍有差别的是,还需要记录它的行标和列标以便输出,
*/
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 # include <stdio.h> 2 int step,flag; 3 int lock[4][4]={false}; 4 int r[16],c[16]; 5 int judge_lock() 6 { 7 int i,j,temp=1; 8 for(i=0;i<4;i++) 9 { 10 for(j=0;j<4;j++) 11 if(lock[i][j] != 1) 12 { 13 temp=0; 14 break; 15 } 16 } 17 return temp; 18 } 19 void turn(int row,int col) 20 { 21 int i,j; 22 for(i=0;i<4;i++) 23 lock[i][col]=!lock[i][col]; 24 lock[row][col]=!lock[row][col];//需要把当前位置再翻转过来, 25 //因为他要求的是本行本列都翻转,但重的那个点不翻转。 26 for(j=0;j<4;j++) 27 lock[row][j]=!lock[row][j]; 28 } 29 void dfs(int row,int col,int deep) 30 { 31 if(deep==step) 32 { 33 flag=judge_lock(); 34 return ; 35 } 36 if(flag==1 || row==4) 37 return ; 38 turn(row,col); 39 r[deep]=row;//只有没达到全部是'-'的时候才记录位置,并且 40 c[deep]=col;//记录的下标是deep,说明当deep不增一的时候此处还需要更新。 41 42 if(col<3) 43 dfs(row,col+1,deep+1); 44 else 45 dfs(row+1,0,deep+1); 46 turn(row,col); 47 if(col<3) 48 dfs(row,col+1,deep); 49 else 50 dfs(row+1,0,deep); 51 52 } 53 int main() 54 { 55 int i,j; 56 char ch[4][4]; 57 for(i=0;i<4;i++) 58 scanf("%s",ch[i]); 59 for(i=0;i<4;i++) 60 { 61 for(j=0;j<4;j++) 62 if(ch[i][j]=='-') 63 lock[i][j]=true; 64 } 65 for(step=0;step<=16;step++) 66 { 67 dfs(0,0,0); 68 if(flag) 69 break; 70 } 71 printf("%d\n",step); 72 for(i=0;i<step;i++) 73 printf("%d %d\n",r[i]+1,c[i]+1); 74 return 0; 75 76 }