洛谷题单指南-进阶搜索-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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
2024-02-18 洛谷题单指南-递推与递归-P2437 蜜蜂路线
2024-02-18 洛谷题单指南-递推与递归-P1928 外星密码