AcWing
  • 首页
  • 活动
  • 题库
  • 竞赛
  • 应用
  • 其它
    • 题解
    • 分享
    • 商店
    • 问答
  • 吐槽
  • 登录/注册

AcWing 845. 八数码    原题链接    中等

作者: 作者的头像   不止步于此 ,  2023-01-25 21:21:00 ,  所有人可见 ,  阅读 20


0


题目描述

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

现在,给你一个初始网格,请你求出得到正确排列至少需要进行多少次交换。

输入格式

输入占一行,将 $3×3$ 的初始网格描绘出来。

例如,如果初始网格如下所示:

1 2 3 
x 4 6 
7 5 8 

则输入为:1 2 3 x 4 6 7 5 8

输出格式

输出占一行,包含一个整数,表示最少交换次数。

如果不存在解决方案,则输出 $−1$。

输入样例:

2 3 4 1 5 x 7 6 8

输出样例

19

有技术的状态表示和状态转移

代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<unordered_map>
using namespace std;

queue<string> q;
unordered_map<string,int> d;
int dx[4] = {-1,0,1,0},dy[4] = {0,1,0,-1};

int bfs(string start)
{
    q.push(start);
    d[start] = 0;

    string end = "12345678x";

    while( q.size() )
    {
        auto t = q.front();
        q.pop();
        int dis = d[t];

        if(t == end) return dis;

        int k = t.find('x');
        int x = k / 3,y = k % 3;

        for( int i = 0 ; i < 4 ; i ++ )
        {
            int a = x + dx[i],b = y + dy[i];
            if(a >= 0 && a < 3 && b >= 0 && b < 3)
            {
                int place = a * 3 + b;
                swap(t[k],t[place]);
                if(!d.count(t))
                {
                    q.push(t);
                    d[t] = dis + 1;
                }
                swap(t[k],t[place]);
            }
        }
    }

    return -1;
}

int main()
{
    char s[2];
    string start;
    for( int i = 0 ; i < 9 ; i ++ )
    {
        scanf("%s",s);
        start += *s;
    }

    printf("%d",bfs(start));

    return 0;
}

0 评论

你确定删除吗?
1024
x

© 2018-2023 AcWing 版权所有  |  京ICP备17053197号-1
用户协议  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标
请输入绑定的邮箱地址
请输入注册信息