八数码问题--bfs

 1 #include<iostream>
 2 #include<cstring>
 3 #define max 1000000
 4 using namespace std;
 5 const int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
 6 string origion;
 7 string goal;
 8 string state[max];
 9 int vis[370000];
10
11 bool encode(string str){  //康拖展开 编码
12     int x=1,sum=0,n=8;
13     for(int i=1;i<9;i++){
14         x=i*x;
15     }
16     for( int i=0 ; i < str.length() ; i++){
17         if( str[i]<=‘9‘ && str[i]>=‘0‘ ){
18             int cnt=0;
19             for(int j=i+1 ; j<str.length() ; j++){
20                 if(str[j]!=‘ ‘&& str[j] < str[i]){
21                     cnt++;
22                 }
23             }
24             sum+=cnt*x;
25             if(x!=1)
26                 x=x/n;
27                 n--;
28         }
29     }
30     if(vis[sum]){
31         vis[sum]=0;
32         return true;
33     }
34     return false;
35 }
36 int bfs(){
37     state[0]=origion;
38     encode(origion);
39     int front=0,rear=1;
40     int floor=0,amt=1;
41     int temp=0;
42
43     while(front!=rear){
44         string str1=state[front],str2=str1;
45         front=(front+1)%max;
46
47         if(amt==0){
48             amt=temp;
49             temp=0;
50             floor++;
51         }
52         if(str1==goal){
53             return floor;
54         }
55         int pos=0,i,j;
56         while(pos<str1.length()){
57             if(str1[pos]==‘0‘) break;
58             pos++;
59         }
60         i=pos/6;
61         j=(pos/2)%3;
62
63         for(int k=0;k<4;k++){
64             str1=str2;
65             int x=i+dir[k][0];
66             int y=j+dir[k][1];
67
68             if(x>=0&&x<3&&y>=0&&y<3){
69                 char t=str1[pos];
70                 str1[pos]=str1[x*6+y*2];
71                 str1[x*6+y*2]=t;
72
73                 if(encode(str1)){
74                     if( (rear+1)%max == front)
75                         return -1;
76                     state[rear]=str1;
77                     rear = (rear+1)%max;
78                     temp++;
79                 }
80
81             }
82         }
83         amt--;
84     }
85     return 0;
86 }
87 int main(){
88     while( getline(cin,origion) && getline(cin,goal)){
89         memset(vis,-1,sizeof(vis));
90         cout<<bfs()<<endl;
91     }
92 }
93 /*
94 2 6 4 1 3 7 0 5 8
95 8 1 5 7 3 6 4 0 2
96 */

原文地址:https://www.cnblogs.com/z-bear/p/8448790.html

时间: 2024-07-31 21:12:17

八数码问题--bfs的相关文章

cdoj 1380 Xiper的奇妙历险(2) [八数码问题 bfs + 预处理]

快要NOIP 2016 了,现在已经停课集训了.计划用10天来复习以前学习过的所有内容.首先就是搜索. 八数码是一道很经典的搜索题,普通的bfs就可求出.为了优化效率,我曾经用过康托展开来优化空间,甚至还用过A*来优化时间.不过这道题懒得写了,就一个普普通通的bfs,再加上一个stl 的map就水过了. 首先题目要求有多达10000组数据,依次搜索肯定是不行的,我试过用A*来写,第2组数据就会T掉,所以我们考虑用一个预处理.从末尾状态搜索所有可行的状态,并用一个map来存储答案.然后就很好写了.

845. 八数码(bfs+map)

在一个3×3的网格中,1~8这8个数字和一个“X”恰好不重不漏地分布在这3×3的网格中. 例如: 1 2 3 X 4 6 7 5 8 在游戏过程中,可以把“X”与其上.下.左.右四个方向之一的数字交换(如果存在). 我们的目的是通过交换,使得网格变为如下排列(称为正确排列): 1 2 3 4 5 6 7 8 X 例如,示例中图形就可以通过让“X”先后与右.下.右三个方向的数字交换成功得到正确排列. 交换过程如下: 1 2 3 1 2 3 1 2 3 1 2 3 X 4 6 4 X 6 4 5 6

HDU 1043 Eight八数码解题思路(bfs+hash 打表 IDA* 等)

题目链接 https://vjudge.net/problem/HDU-1043 经典的八数码问题,学过算法的老哥都会拿它练搜索 题意: 给出每行一组的数据,每组数据代表3*3的八数码表,要求程序复原为初始状态 思路: 参加网站比赛时拿到此题目,因为之前写过八数码问题,心中暗喜,于是写出一套暴力bfs+hash,结果TLE呵呵 思路一:bfs+hash(TLE) 1 #include <cstdio> 2 #include <cstring> 3 #include <queu

BFS(八数码) POJ 1077 || HDOJ 1043 Eight

题目传送门1 2 题意:从无序到有序移动的方案,即最后成1 2 3 4 5 6 7 8 0 分析:八数码经典问题.POJ是一次,HDOJ是多次.因为康托展开还不会,也写不了什么,HDOJ需要从最后的状态逆向搜索,这样才不会超时.判重康托展开,哈希也可. POJ //#include <bits/stdc++.h> #include<iostream> #include<algorithm> #include<string> #include<stack

八数码问题+路径寻找问题+bfs(隐式图的判重操作)

Δ路径寻找问题可以归结为隐式图的遍历,它的任务是找到一条凑够初始状态到终止问题的最优路径, 而不是像回溯法那样找到一个符合某些要求的解. 八数码问题就是路径查找问题背景下的经典训练题目. 程序框架 process()  初始化vis数组,初始化初始节点到目标节点的移动距离 dfs()搜索到每一个节点,如果不是目标节点,对其依次扩展所有子节点,并判重,全部子节点搜索完全后,改变父节点:如果是目标节点成功返回 输出最少移动步数 input: 2 6 4 1 3 7 0 5 8 8 1 5 7 3 6

【算法】BFS+哈希解决八数码问题

15拼图已经有超过100年; 即使你不叫这个名字知道的话,你已经看到了.它被构造成具有15滑动砖,每一个从1到15上,并且所有包装成4乘4帧与一个瓦块丢失.让我们把丢失的瓷砖"X"; 拼图的目的是安排瓷砖以便它们排序为: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15× 这里唯一合法经营是交流'X'与它共享一个边缘的瓷砖之一.作为一个例子,举动下列顺序解决了一个稍微加扰难题: 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 5 6 7 8 5 6

UVALive 6665 Dragon&#226;??s Cruller --BFS,类八数码问题

题意大概就是八数码问题,只不过把空格的移动方式改变了:空格能够向前或向后移动一格或三格(循环的). 分析:其实跟八数码问题差不多,用康托展开记录状态,bfs即可. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <vector> #include <queue&g

poj 1077 八数码(BFS+康托展开)

1 /* 2 题意:八数码问题,给出3*3的矩阵含1~8以及x,给出一个符合的解使得移动后的矩阵的顺序为1~8,最后为x 3 4 题解:BFS 5 需要用到康托展开来表示状态,不然数组无法完全表示所有状态,这样BFS就无法判断找不到解的情况(status 6 的0ms,0KB究竟是怎么做到的,简直不能想象=.=) 7 */ 8 #include <cstdio> 9 #include <cstring> 10 #include <queue> 11 #include &

HDU 1043 Eight (BFS&#183;八数码&#183;康托展开)

题意  输出八数码问题从给定状态到12345678x的路径 用康托展开将排列对应为整数  即这个排列在所有排列中的字典序  然后就是基础的BFS了 #include <bits/stdc++.h> using namespace std; const int N = 5e5, M = 9; int x[4] = { -1, 1, 0, 0}; int y[4] = {0, 0, -1, 1}; int fac[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320