Flip Game(枚举)

给十六个格子标上序号

                                        0     1     2     3

                                        4     5     6     7

                                        8     9     10    11

                                        12   13   14    15

便可以采用二进制记录不同的状态

                      0    1    0    0    0    1    1    0    0    0    1    1    0    1    1    1

                     15   14  13  12   11  10  9    8    7    6    5    4    3    2    1    0

                                                  此时便记录下了

                         14        10         9         5        4          2          1      0

最后采用十进制保存此时的状态 1表示‘b’,0表示‘w’,再做相应的翻转,既0 -> 1,  1 -> 0

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 char ma[5][5];//用于输入
 5 int states[65535]={0};//(核心部分)记录状态因为最大为2^16-1=65535所以数组大小为65535
 6 int step[65535]={0};//记录步数
 7 int rear=0,front=0;//记录头与尾
 8 bool vis[65535];//用于记录是否搜过
 9 
10 //输入,并记录初始状态,放入队列首位置
11 void shuru()
12 {
13     int i,state=0;
14     for(i=0;i<4;i++){
15         cin>>ma[i];
16         int j;
17         for(j=0;j<4;j++)
18             if(ma[i][j]=='b')
19                 state|=1<<(i*4+j);
20     }
21     states[rear++]=state;//记录初始状态放入队列首
22     vis[state]=true;//记录已走过
23 }
24 
25 //反转一个,并产生影响
26 int fanzhuan(int stat,int i)
27 {
28     int state=0;
29     state|=1<<i;
30     if(i%4!=0)state|=1<<(i-1);
31     if((i+1)%4!=0)state|=1<<(i+1);
32     if(i-4>=0)state|=1<<(i-4);
33     if(i+4<16)state|=1<<(i+4);
34     return (state^stat);
35 }
36 
37 //BFS宽度遍历,搜索每种状态,不断放入队列中,找到后立即返回真(true)
38 bool bfs()
39 {
40     while(front<rear)
41     {
42         int state=states[front++];//取出队列头,记录此时状态
43         if(0==state||65535==state)//一旦找到,立即返回
44         {
45             cout<<step[state]<<"\n";
46             return true;
47         }
48         int i;
49         for(i=0;i<16;i++)//遍历每种状态
50         {
51             int st;
52             st=fanzhuan(state,i);
53             if(!vis[st])//防止重复遍历
54             {
55                 states[rear++]=st;//不可以的加到队列尾部
56                 vis[st]=true;
57                 step[st]=step[states[front-1]]+1;//步数加1
58             }
59         }
60     }
61     return false;
62 }
63 int main()
64 {
65     //freopen("in.txt","r",stdin);
66     //freopen("out.txt","w",stdout);
67     shuru();
68     if(!bfs())cout<<"Impossible\n";
69     return 0;
70 }

 

转载于:https://www.cnblogs.com/gj-Acit/archive/2013/01/28/2879714.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值