原题链接
在一个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
4 5 6
7 5 8
7 5 8
7 X 8
7 8 X
把“X”与上下左右方向数字交换的行动记录为“u”、“d”、“l”、“r”
。
现在,给你一个初始网格,请你通过最少的移动次数,得到正确排列。
输入格式
输入占一行,将3×3的初始网格描绘出来。
例如,如果初始网格如下所示:
1 2 3
x 4 6
7 5 8
则输入为:1 2 3 x 4 6 7 5 8
输出格式
输出占一行,包含一个字符串,表示得到正确排列的完整行动记录。如果答案不唯一,输出任意一种合法方案即可。
如果不存在解决方案,则输出”unsolvable”
。
输入样例:
2 3 4 1 5 x 7 6 8
输出样例
ullddrurdllurdruldr
A star算法是一直沿着某条估计出来的路劲搜索的,且估计出来的路劲一定要小于等于实际路劲
A star的形式与Dijkstra的形式非常接近(Dijkstra估计函数为0),但是Dijkstra在每次出队之后就已经定下来出队点已是最小距离,而A star不行。A star只能保证终点状态是最小的。
八数码问题若序列中的逆序对数量为奇数个则无法走到终点
这里估价函数采用曼哈顿距离,为理想状态每个位置(如‘1’ 在(1,1)上)到终点位置('1'的终点坐标(0,0))的曼哈顿距离(则此时'1'的曼哈顿距离为2)之和。这样的算出来的距离一定小于等于实际上该状态到终点的最小距离
#include<iostream>
#include<algorithm>
#include<unordered_map>
#include<queue>
#include<string>
using namespace std;
int dx[] = {
-1,0,1,0};
int dy[] = {
0,1,0,-1};
char op[5] = "urdl";
int f(string state)
{
//曼哈顿估价函数,估价值为每个位置离终点的曼哈顿距离之和