先列出题目:

1、POJ 1753

POJ 1753  Flip Game:http://poj.org/problem?id=1753

 

Sample Input

bwwb
bbwb
bwwb
bwww

Sample Output

4

入手竟然没有思路,感觉有很多很多种情况需要考虑,也只能使用枚举方法才能解决了吧~

4x4的数组来进行数据存储的话操作起来肯定非常不方便,这里借用位压缩的方法来存储状态,使用移位来标识每一个位置的的上下左右的位置操作。 详细看这里

 

1、当棋盘状态id为0(全白)或65535(全黑)时,游戏结束,0^1=1,1^1=0,所以翻转的操作可以通过异或操作来完成,而翻转的位置可以通过移位来确定。

2、结束标识!!!!!

 

 

分步骤:

1、从输入到位标识状态:

 1     int state = 0;
 2     char ch[4];
 3 
 4     while(cin>>ch)
 5     {
 6        for(int j = 0 ; j < 4 ; j++)
 7         {
 8             state = state<<1;
 9             if(ch[j] == 'b')
10                 state += 1;
11         }
12     }

2、从一个状态到下一个状态的的转换,比如对应位置i处进行改变后得到的状态:

这里的16个数据使用代码生成可能是想不到的,但是可以通过手动变换一次获得~~~

其实相当于

0 0 0 0

0 0 0 0

0 0 0 0

0 0 0 0

在每一个位置进行变换后的状态记录,正好对应疑惑的16个数据

 1 int change[16] ={
 2      51200,58368,29184,12544,
 3      35968,20032,10016,4880,
 4      2248,1252,626,305,
 5      140,78,39,19
 6 };
 7 
 8 state = state^change[i];//对应第i个位置的改变
 9 
10 //上面的16个数据是由下面的代码得来的
11 
12 int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
13 void init()
14 {
15     int i,j,x,y,t,temp;
16     for(i=0;i<4;++i)
17     {
18         for(j=0;j<4;++j)
19         {
20             temp = 0;
21             temp ^= (1<<((3-i)*4+3-j));   //第一行代表16位的高4位,同理第一列也代表高位,所以棋盘(i,j)处在16位中的位置是((3-i)*4+3-j)
22 
23             for(t=0;t<4;++t)
24             {
25                 x = i + dir[t][0];
26                 y = j + dir[t][1];
27                 if(x<0 || y<0 || x>3 || y>3)
28                     continue;
29                 temp ^= (1<<((3-x)*4+3-y));
30             }
31             cout<<temp<<" ";
32         }
33         cout<<endl;
34     }
35 }

3、判断是否满足情况只需要判断state == 0 || state == 65535 即可。

4、解决了小问题,再思考一下大逻辑:

初始状态即为纯色则直接输出0,初始不是纯色,翻转一个的状态是纯色,则输出1,翻转一个会产生n种状态,0<=n<=16,这些状态要放入到队列中进行保存,再从中出队列再进行下一次的翻转。关键问题是什么情况下判定翻转结束,仍然没有纯色出现,则输出impossible,大于2次的翻转的初态都是从队列中取出来的,必须提前设计一个状态标识,表明同一种状态不再次进行入队列,那么当队列为空时才可以下结论。

 1 //需要设置一个是否处理过的标识,共有状态有65536个,即0-65535,
 2 //如果对应位置被标记为1了,则说明已经处理过,直接抛弃进行下一次
 3 
 4 //这样的遍历过程被称为BFS的过程
 5 
 6 
 7 bool visit[65536];
 8 
 9 int bfs(int state)//返回值是进行的步数,impossible为-1
10 {
11     queue<Node> q;
12     Node current,next;
13 
14     current.state = state;
15     current.step = 0;
16     q.push(current);
17     visited[state] = true;
18 
19     while(!q.empty())
20     {
21         current = q.front();
22         q.pop();
23 
24         if(current.state == 0 || current.state == 65535)
25             return current.step;
26 
27         for(int i = 0;i<16;i++)//每一种状态都要进行16次操作
28         {
29             next.state = current.state^change[i];
30             next.step = current.step+1;
31 
32             if(next.state == 0 || next.state == 65535)
33                 return next.step;
34             else
35             {
36                 if(visited[next.state])
37                     continue;
38                 else
39                 {
40                     visited[next.state] = true;
41                     q.push(next);
42                 }
43             }
44         }
45     }
46     return -1;
47 }

总结:枚举,此题就是使用枚举的思想来找到需要的解,尤其是使用队列来进行一个的while循环来进行的。

这里记录一下全部代码:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include<queue>
 4 
 5 using namespace std;
 6 
 7 int change[16] ={
 8      51200,58368,29184,12544,
 9      35968,20032,10016,4880,
10      2248,1252,626,305,
11      140,78,39,19
12 };
13 
14 struct Node
15 {
16     int state;
17     int step;
18 };
19 int state = 0;
20 bool visited[65536];
21 
22 int bfs(int state)//返回值是进行的步数,impossible为-1
23 {
24     queue<Node> q;
25     Node current,next;
26 
27     current.state = state;
28     current.step = 0;
29     q.push(current);
30     visited[state] = true;
31 
32     while(!q.empty())
33     {
34         current = q.front();
35         q.pop();
36 
37         if(current.state == 0 || current.state == 65535)
38             return current.step;
39 
40         for(int i = 0;i<16;i++)//每一种状态都要进行16次操作的
41         {
42             next.state = current.state^change[i];
43             next.step = current.step+1;
44 
45             if(next.state == 0 || next.state == 65535)
46                 return next.step;
47             else
48             {
49                 if(visited[next.state])
50                     continue;
51                 else
52                 {
53                     visited[next.state] = true;
54                     q.push(next);
55                 }
56             }
57         }
58     }
59     return -1;
60 }
61 
62 int main()
63 {
64     char ch[4];
65     while(cin>>ch)
66     {
67        for(int j = 0 ; j < 4 ; j++)
68         {
69             state = state<<1;
70             if(ch[j] == 'b')
71                 state += 1;
72         }
73     }
74 
75     memset(visited,false,sizeof(visited));
76     int count = bfs(state);
77     if(count == -1)
78         cout<<"Impossible";
79     else
80         cout<<count;
81     return 0;
82 }
View Code

相关文章:

  • 2022-12-23
  • 2022-01-11
  • 2022-02-18
  • 2022-01-22
  • 2022-01-05
  • 2022-12-23
  • 2021-07-12
猜你喜欢
  • 2021-11-29
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2018-03-01
  • 2022-12-23
  • 2021-07-11
相关资源
相似解决方案