Acwing 179 八数码问题 (bfs or A*)

2020-12-26 21:28

阅读:406

标签:map   解决方案   ios   order   hang   vector   push   bfs   乱序   

题面

在一个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

思路

直接bfs就可以了,这里由于我们需要把操作给记录下来,那么我们就需要沿着路线进行一个回溯,那么我们可能需要去保存当前状态的一个前状态和操作。用map可以解决。A*的做法的话我们需要一个有限队列并且加入估价函数,这里的估价函数就是所有乱序数字曼哈顿距离之和。

代码实现

#include
#include
#include
#include
#include
#include
using namespace std;

char change[5]="drul";
int moves[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
string target="12345678x";

unordered_map  p2;
unordered_map  p1;

inline int bfs (string s) {
     queue  q;
     
     q.push (s);
     p1[s]=0;
     while (q.size ()) {
         string sh=q.front ();
         string h=sh;
         q.pop ();

         if (sh==target) return true;

         int k=sh.find (‘x‘);
         int x=k/3,y=k%3;
         for (int i=0;i=0&&a=0&&b>c, s+=c;
    
    if  (bfs (s)) {
        vector  arr;
        string ans=target;
        while (ans!=s) {
            arr.push_back (change[p1[ans]]);
            ans=p2[ans];
        }
        for (int i=arr.size ()-1;i>=0;i--) {
            cout

Acwing 179 八数码问题 (bfs or A*)

标签:map   解决方案   ios   order   hang   vector   push   bfs   乱序   

原文地址:https://www.cnblogs.com/hhlya/p/13363937.html


评论


亲,登录后才可以留言!