【BFS】八数码问题

描述

  八方块移动游戏要求从一个含 8 个数字(用 1-8 表示)的方块以及一个空格方块(用 0 表示)的 3 × 3 矩阵的起始状态开始,不断移动该空格方块以使其和相邻的方块互换,直至达到所定义的目标状态。空格方块在中间位置时有上、下、左、右 4 个方向可移动,在四个角落上有 2个方向可移动,在其他位置上有 3 个方向可移动。例如,假设一个 3× 3 矩阵的初始状态为:

8 0 3
2 1 4
7 6 5

目标状态为:

1 2 3
8 0 4
7 6 5

则一个合法的移动路径为:

8 0 3  >  8 1 3  >  8 1 3 >  0 1 3 >  1 0 3  >  1 2 3
2 1 4  >  2 0 4  >  0 2 4 >  8 2 4 >  8 2 4  >  8 0 4
7 6 5  >  7 6 5  >  7 6 5 >  7 6 5 >  7 6 5  >  7 6 5

  另外,在所有可能的从初始状态到目标状态的移动路径中,步数最少的路径被称为最短路径;在上面的例子中,最短路径为 5 。如果不存在从初试状态到目标状态的任何路径,则称该组状态无解。

问题

  请设计有效的(细节请见评分规则)算法找到从八方块的某初试状态到某目标状态的所有可能路径中的最短路径。

输入

  程序需读入初始状态和目标状态,这两个状态都由 9 个数字组成( 0 表示空格, 1-8 表示 8个数字方块),每行 3 个数字,数字之间用空格隔开。

输出

  如果输入数据有解,输出一个表示最短路径的非负的整数;如果输入数据无解,输出 -1 。

输入样例1

8 0 3
2 1 4
7 6 5
1 2 3
8 0 4
7 6 5

  

输出样例1

5

  

解题思路

  这道题我把图存成字符串,再用map映射步数,还用了九维数组打标记(笑哭)。剩下的就还是搜索下去。

题解

 1 #include<bits/stdc++.h>
 2 #define for(i,a,b) for(int i=a;i<=b;i++)//宏定义,很好用
 3 using namespace std;
 4 string x,y;
 5 bool mp[9][9][9][9][9][9][9][9][9];//
 6 map<string,int> sj;//map映射标记
 7 queue<string> q;//队列,BFS标配
 8 int dir[9][4]={-1,-1,3,1, -1,0,4,2, -1,1,5,-1, 0,-1,6,4, 1,3,7,5, 2,4,8,-1, 3,-1,-1,7, 4,6,-1,8, 5,7,-1,-1};//九个点上下左右分别的下标(-1代表越界)
 9 void bfs(string a)
10 {
11     sj[a]=1;//
12     q.push(a);
13     while(!q.empty())
14     {
15         int b;
16         a=q.front();
17         q.pop();
18         if(a==y){cout<<sj[a]-1;return;}//因为初始状态为1,所以要减一
19         for(i,0,a.size()-1)
20         {
21             if(a[i]==‘0‘)b=i;//记0的位置
22         }
23         for(i,0,3)
24         {
25             string aa=a;
26             if(dir[b][i]==-1)continue;//下标无效
27             swap(aa[b],aa[dir[b][i]]);//交换
28             if(sj[aa]==0)
29             {
30                 sj[aa]=sj[a]+1;//步数加一
31                 q.push(aa);//入队列
32             }
33         }
34     }
35     cout<<-1;//不行就输出-1
36 }
37 int main()
38 {
39     for(i,1,3)
40     for(j,1,3)
41     {
42         char a;
43         cin>>a;
44         x+=a; //字符串存储
45     }
46     for(i,1,3)
47     for(j,1,3)
48     {
49         char a;
50         cin>>a;
51         y+=a; //字符串存储
52     }
53     bfs(x);//开始搜索
54     return 0;
55 }

原文地址:https://www.cnblogs.com/hualian/p/11153083.html

时间: 2024-10-25 16:29:36

【BFS】八数码问题的相关文章

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

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

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

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

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

八数码问题+路径寻找问题+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 &

UVA 10085(bfs+康拓展开)八数码问题

Description Problem A The Most Distant State Input: standard input Output: standard output The 8-puzzle is a square tray in which eight square tiles are placed. The remaining ninth square is uncovered. Each tile has a number on it. A tile that is adj

每天刷个算法题20160526:BFS解决八数码问题(九宫格问题)

版权所有.所有权利保留. 欢迎转载,转载时请注明出处: http://blog.csdn.net/xiaofei_it/article/details/51524864 为了防止思维僵化,每天刷个算法题.已经刷了几天了,现在发点代码. 我已经建了一个开源项目,每天的题目都在里面: https://github.com/Xiaofei-it/Algorithms 绝大部分算法都是我自己写的,没有参考网上通用代码.读者可能会觉得有的代码晦涩难懂,因为那是我自己的理解. 最近几天都是在写一些原来的东西