poj1753 搜索,枚举法
1 ///2014.2.28 - 2014.3.1 2 ///poj1753 3 4 /** 5 *题意: 6 *给你一个4*4的黑白棋盘,通过翻棋子使棋盘变为全白或全黑, 7 *(以下“翻一个位置”皆指翻着个位置和它周围的四个棋子。) 8 *翻子时四周的四个棋子如果存在的话颜色也会跟着改变。 9 *问最少需要多少步可以使棋盘变为一种颜色。 10 ** 11 *思路: 12 *每一次翻子会改变这个棋子和它周围的四个棋子的颜色, 13 *所以在一个解中一个位置的棋子只应翻一次, 14 *同时在不同的位置间翻子的顺序是对最后翻完后的结果没有影响的。 15 *所以可以逐次翻每一个位置,如果翻到最后发现不能使棋盘一色, 16 *则回过头来将这个位置翻回来。接着往下翻。 17 */ 18 19 #include <cstdio> 20 #include <iostream> 21 #include <algorithm> 22 using namespace std; 23 24 int chess; ///二进制末16位表示棋盘,1表示黑、0表示白 25 int step; 26 bool flag = false; ///标记是否是已经找到解 27 28 void flip(int i) ///翻子函数 29 { 30 if( i-4>=0 ) chess = chess ^ ( 0x1<<(i-4) ); 31 if( i-1>=0 && i%4 ) chess = chess ^ ( 0x1<<(i-1) ); ///判断条件中 i%4 是判断是否是边界的棋子 32 chess = chess ^ 0x1<<i; 33 if( i+1<=15 && (i+1)%4 ) chess = chess ^ ( 0x1<<(i+1) );///同上 (i+1)%4 是判断是否是边界的棋子 34 if( i+4<=15 ) chess = chess ^ ( 0x1<<(i+4) ); 35 } 36 37 void dfs(int i,int deep) ///deep表示搜索的深度,也是翻棋子的次数 38 { 39 if( step == deep ){ 40 flag = ( chess==65535 || chess==0 ); ///65535 和 0 分别表示全黑和全白 41 return; 42 } 43 if( i>15 || flag ) return; 44 flip(i); 45 dfs(i+1,deep+1); 46 if( !flag ){ 47 flip(i); 48 dfs(i+1,deep); 49 } 50 return; 51 } 52 53 void init() 54 { 55 chess = 0; 56 char temp; 57 for(int i=0 ; i<16 ; i++){ 58 cin>>temp; 59 if( temp == 'b' ){ 60 chess = chess | 0x1 << i ; 61 } 62 } 63 } 64 65 int main( ) 66 { 67 // freopen("in","r",stdin); 68 // freopen("out","w",stdout); 69 70 init(); 71 72 for(step=0 ; step<=16 ; step++ ){ 73 dfs(0,0); 74 if( flag ) 75 break; 76 } 77 if( !flag ) 78 cout<<"Impossible"<<endl; 79 else 80 cout<<step<<endl; 81 return 0; 82 }