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 }
下面是正确代码:
有两个学习要点: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 }
以上是关于AOJ 0121 Seven Puzzle(反向BFS+map)的主要内容,如果未能解决你的问题,请参考以下文章