洛谷题单指南-进阶搜索-P1379 八数码难题

原题链接:https://www.luogu.com.cn/problem/P1379

题意解读:3*3的棋盘,从起始状态到目标状态最少需要几步。

解题思路:这是一种最小步数模型,通过BFS可以得到最短路径。

与之前不同的是,整个棋盘可以看做是一种状态,从一种状态可以最多扩展出四种状态,对应0的上、下、左、右移动。

那么,需要解决的问题是,如何将棋盘状态进行hash表示,这里直接用字符串即可,借助于unordered_map<string,int>即可记录某个状态距离起始状态的距离。

这里还需要将坐标在二维和一维之间转换,比如在字符串中'0'的位置是pos,那么在棋盘中的坐标就是(pos / 3, pos % 3);而在棋盘中的坐标(x, y)对应到字符串中的位置则是x * 3 + y。

剩下的,就是常规的BFS求最短路过程。

当然,此题还可以用双向BFS或者A*算法优化,只不过这里直接用BFS就能AC,就不那么麻烦了。

100分代码:

#include <bits/stdc++.h>
using namespace std;

string s;
string target = "123804765";
unordered_map<string, int> dist;
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};

void bfs(string start)
{
    queue<string> q;
    q.push(start);
    dist[start] = 0;
    while(q.size())
    {
        string stat = q.front(); q.pop();
        if(stat == target) // 判断是否到达目标状态
        {
            cout << dist[stat];
            return;
        }
        int pos = stat.find('0'); // 字符串中0的位置
        int x = pos / 3, y = pos % 3; // 棋盘中0的位置
        for(int i = 0; i < 4; i++)
        {
            int nx = x + dx[i], ny = y + dy[i]; // 0移动后的位置
            if(nx < 0 || nx > 2 || ny < 0 || ny > 2) continue;
            int npos = nx * 3 + ny; // 0移动后在字符串中的位置
            string tmp = stat; 
            swap(tmp[pos], tmp[npos]);
            if(!dist.count(tmp)) 
            {
                q.push(tmp);
                dist[tmp] = dist[stat] + 1;
            }
        }
    }
}

int main()
{
    cin >> s;
    bfs(s);
    return 0;
}

 

posted @   五月江城  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
历史上的今天:
2024-02-18 洛谷题单指南-递推与递归-P2437 蜜蜂路线
2024-02-18 洛谷题单指南-递推与递归-P1928 外星密码
点击右上角即可分享
微信分享提示