AOJ 0121 Seven Puzzle(反向BFS+map)

Posted xiaoxb17

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AOJ 0121 Seven Puzzle(反向BFS+map)相关的知识,希望对你有一定的参考价值。

卡了很久的一道题,之前用正向BFS硬缸,结果凉凉,下面是之前错误的代码,仅供自己记录,他人浏览请直接跳过:

技术图片
  1 #include<cstring>
  2 #include<iostream>
  3 #include<queue>
  4 #include<algorithm>
  5 #include<cstdio>
  6 
  7 using namespace std;
  8 
  9 int tmaze[2][4];
 10 struct node{
 11     int maze[2][4];
 12     int x;
 13     int y;
 14     int laststep; ///1、2、3、4、0分别带表上一步走上、下、左、右(0表示初始节点)
 15     int coun; ///记录走到当前状态走了多少步
 16     node(){}
 17     node(int xi,int yi,int step,int c){
 18         x=xi;
 19         y=yi;
 20         laststep=step;
 21         coun=c;
 22         for(int i=0;i<2;i++){
 23             for(int j=0;j<4;j++)
 24                 maze[i][j]=tmaze[i][j];
 25         }
 26     }
 27 };
 28 
 29 int dx[4]={1,-1,0,0};
 30 int dy[4]={0,0,-1,1};
 31 int ans;
 32 int sx,sy;
 33 
 34 bool isok(){
 35     for(int i=0;i<2;i++){
 36         for(int j=0;j<4;j++)
 37             if(tmaze[i][j]!=4*i+j){
 38                 return false;
 39             }
 40     }
 41     return true;
 42 }
 43 
 44 int bfs(){
 45     ans=0;
 46     queue<node> que;
 47     que.push(node(sx,sy,0,0));
 48     while(que.size()){
 49         int x=que.front().x;
 50         int y=que.front().y;
 51         int s=que.front().laststep;
 52         int c=que.front().coun;
 53         for(int i=0;i<2;i++){
 54             for(int j=0;j<4;j++){
 55                 tmaze[i][j]=que.front().maze[i][j];
 56                 printf("%d ",que.front().maze[i][j]);
 57             }
 58         }
 59         printf("
");
 60         que.pop();
 61         if(isok()){
 62             return c;
 63         }
 64         if(x==0&&(s!=1||s==0)){ ///可以与下面的交换
 65             int t=tmaze[x][y]; tmaze[x][y]=tmaze[1][y]; tmaze[1][y]=t;
 66             que.push(node(1,y,2,c+1));
 67             t=tmaze[x][y]; tmaze[x][y]=tmaze[1][y]; tmaze[1][y]=t;
 68         }
 69         if(x==1&&(s!=2||s==0)){ ///可以与上面的交换
 70             int t=tmaze[x][y]; tmaze[x][y]=tmaze[0][y]; tmaze[0][y]=t;
 71             que.push(node(0,y,1,c+1));
 72             t=tmaze[x][y]; tmaze[x][y]=tmaze[0][y]; tmaze[0][y]=t;
 73         }
 74         if(y>0&&(s!=4||s==0)){ ///可以与左边的交换
 75             int t=tmaze[x][y]; tmaze[x][y]=tmaze[x][y-1]; tmaze[x][y-1]=t;
 76             que.push(node(x,y-1,3,c+1));
 77             t=tmaze[x][y]; tmaze[x][y]=tmaze[x][y-1]; tmaze[x][y-1]=t;
 78         }
 79         if(y<3&&(s!=3||s==0)){ ///可以与右边的交换
 80             int t=tmaze[x][y]; tmaze[x][y]=tmaze[x][y+1]; tmaze[x][y+1]=t;
 81             que.push(node(x,y+1,4,c+1));
 82             t=tmaze[x][y]; tmaze[x][y]=tmaze[x][y+1]; tmaze[x][y+1]=t;
 83         }
 84     }
 85     return 0;
 86 }
 87 
 88 void solve(){
 89     for(int i=0;i<2;i++){
 90         for(int j=0;j<4;j++){
 91             scanf("%d",&tmaze[i][j]);
 92             if(tmaze[i][j]==0){
 93                 sx=i; sy=j;
 94             }
 95         }
 96     }
 97     printf("%d
",bfs());
 98 }
 99 
100 int main(){
101     solve();
102     return 0;
103 }
View Code

 

下面是正确代码:

   有两个学习要点:1、map的使用

                          2、如何把读入的整形数字变成字符串

看代码:

技术图片
 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 #include <map>
 5 #include <queue>
 6 
 7 using namespace std;
 8 
 9 map<string, int> dp;
10 int direction[4] = { 1, -1, 4, -4 };
11 
12 // 让0漫游整个字符串,结果存在map中(反向bfs)
13 void bfs()
14 {
15 
16     queue<string> que;
17     que.push("01234567");
18     dp["01234567"] = 0;
19     while (que.size())
20     {
21         string now = que.front(); que.pop();
22         // p是‘0‘的位置
23         int p = 0;
24         for (int j = 0; j < 8; ++j)
25         {
26             if (now[j] == 0)
27             {
28                 p = j;
29                 break;
30             }
31         }
32         for (int i = 0; i < 4; ++i)
33         {
34             int n = p + direction[i];
35             if (0 <= n && n < 8 &&
36                 !(p == 3 && i == 0) && // 右上角不能再往右了
37                 !(p == 4 && i == 1))   // 左下角不能再往左了
38             {
39                 string next = now;
40                 swap(next[p], next[n]);
41                 //这里避免的重复搜索,只有没有搜索过的状态才加入map和队列中
42                 if (dp.find(next) == dp.end())
43                 {
44                     dp[next] = dp[now] + 1;
45                     que.push(next);
46                 }
47             }
48         }
49     }
50 }
51 
52 
53 int main()
54 {
55     bfs();
56     string line;
57     while (getline(cin, line))
58     {
59         //读入是一个学习要点,整行读入,在把空格去掉
60         //注意remove()函数不是string类中的,是STL中的(在头文件algorithm中)
61         line.erase(remove(line.begin(), line.end(),  ), line.end());
62         cout << dp[line] << endl;
63     }
64     return 0;
65 }
View Code

 

以上是关于AOJ 0121 Seven Puzzle(反向BFS+map)的主要内容,如果未能解决你的问题,请参考以下文章

aoj 0121 Seven Puzzle

AOJ 0121: Seven PuzzleBFS

AOJ0121 Seven PuzzleBFS

python AOJ_ITP1_6_B查找丢失的卡片

aoj 0005 GCD and LCM

AOJ_ALDS1_10_C Longest Common SubsequenceLCS+DP