poj 1753

用位操作+BFS解决.基本思想如下:
给棋盘每一个状态赋予一个状态id,id计算方法是将棋盘与数的二进制表示联系起来,如题所给的数据:
bwwb
bbwb
bwwb
bwww
状态id为6585,计算方法为1*2^0+0*2^1+1*2^2..1*2^12+0*2^13..=6585(其中b代表1,w代表0)
在此基础上进行BFS搜索,首先理解一点,先点(0,0)再点(0,1)与先点(0,1)再点(0,0)对结果不造成任何影响.因此遍历棋盘的16个位置,将每次点击后的状态id利用树状结构保存.如:
                                 6585
                               /   |   \  ...
                           (0,0) (0,1)  (0,2)
                            /      |      \  ...
                         6568     6553     6646
                      ...............................
对此树进行BFS搜索,将id为0(全白)或65535(全黑)的时候则搜索成功,输出树的高度,否则输出"Impossible".
为了提高搜索效率,采用位运算,如果想将整数的二进制某一位翻转可采用id^=(1<<x)(x代表要翻转的位置)
 1  #include  " assert.h "
 2  #include  < iostream >
 3  #include  < queue >
 4  using   namespace  std;
 5 
 6  const   int  MAX_STATE  =   65536 ;
 7  const   int  ALL_WHILE_STATE  =   0 ;
 8  const   int  ALL_BLACK_STATE  =   65535 ;
 9  const   int  WIDTH_OF_BOARD  =   4 ;
10  const   int  SIZE_OF_BOARD  =  WIDTH_OF_BOARD  *  WIDTH_OF_BOARD;  //  4 * 4
11 
12  int  ConvertPieceColorToInt( char  color)
13  {
14       switch (color)
15      {
16       case   ' b ' :
17           return   1 ;
18       case   ' w ' :
19           return   0 ;
20      }
21  }
22 
23  int  FlipPiece( int  state_id,  int  position)
24  {
25      state_id  ^=  ( 1   <<  position);
26 
27       //  up
28       if (position  -   4   >=   0 )
29          state_id  ^=  ( 1   <<  (position  -   4 ));
30       //  down
31       if (position  +   4   <  SIZE_OF_BOARD)
32          state_id  ^=  ( 1   <<  (position  +   4 ));
33       //  left
34       if (position  %   4   !=   0 )
35          state_id  ^=  ( 1   <<  (position  -   1 ));
36       //  right
37       if (position  %   4   !=   3 )
38          state_id  ^=  ( 1   <<  (position  +   1 ));
39 
40       return  state_id;
41  }
42 
43  int  _tmain( int  argc, _TCHAR *  argv[])
44  {
45       int  current_state_id  =   0 ;
46       int  state[MAX_STATE];
47      queue < int >  search_queue;
48 
49      memset(state,  - 1 sizeof (state));
50 
51       char  color;
52 
53       for ( int  i  =   0 ; i  <  SIZE_OF_BOARD;  ++ i)
54      {
55          cin  >>  color;
56          current_state_id  +=  ConvertPieceColorToInt(color)  <<  i;
57      }
58 
59       if (current_state_id  ==  ALL_WHILE_STATE
60           ||  current_state_id  ==  ALL_BLACK_STATE)
61      {
62          cout  <<   " 0 "   <<  endl;
63           return   0 ;
64      }
65 
66      state[current_state_id]  =   0 ;
67      search_queue.push(current_state_id);
68 
69       int  next_state_id;
70 
71       while ( ! search_queue.empty())
72      {
73          current_state_id  =  search_queue.front();
74          search_queue.pop();
75 
76           for ( int  i  =   0 ; i  <  SIZE_OF_BOARD;  ++ i)
77          {
78              next_state_id  =  FlipPiece(current_state_id, i);
79               if (next_state_id  ==  ALL_WHILE_STATE
80                   ||  next_state_id  ==  ALL_BLACK_STATE)
81              {
82                  cout  <<  state[current_state_id]  +   1   <<  endl;
83                   return   0 ;
84              }
85              assert(next_state_id  <  MAX_STATE);
86               if (state[next_state_id]  ==   - 1   /*  not visited  */ )
87              {
88                  state[next_state_id]  =  state[current_state_id]  +   1 ;
89                  search_queue.push(next_state_id);
90              }
91          }
92      }
93 
94      cout  <<   " Impossible "   <<  endl;
95       return   0 ;
96  }
97 
98 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值