洛谷题单指南-进阶搜索-P2324 [SCOI2005] 骑士精神
原题链接:https://www.luogu.com.cn/problem/P2324
题意解读:在5*5棋盘,12个0,12个1,还有一个*,0或1可以和*交换,交换的两个位置必须是类似马走日,给定初始状态,求最少经过多少步可以到达目标状态。
解题思路:要计算最少步数,首先想到BFS,但是由于每一步有8种状态,直接BFS必然超时爆内存。
题目限制在15步之内,可以采用迭代加深方式,再加上启发性剪枝,也就是IDA*算法,才能通过本题。
所谓IDA*算法, 就是在迭代加深的基础上,每次判断当前状态stat已搜索步数和最大步数的关系if(depth > maxdepth) return false时,加入一个估价函数f(stat),f(stat)表示从当前状态stat到达目标状态的最小步数,剪枝变成:
if(depth + f(start) > maxdepth) return false;
这样可以极大减少搜索的状态数。
对于本题,估价函数可以这样设计:统计每个位置与目标位置不同的个数,不考虑*所在位置的不同,因为0/1如果归位了,*自然就归位了。
100分代码:
#include <bits/stdc++.h>
using namespace std;
int t;
/*
目标终点:
11111
01111
00*11
00001
00000
转化成一维:111110111100*110000100000
*/
string target = "111110111100*110000100000";
int dx[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
int dy[8] = {1, 2, 2, 1, -1, -2, -2, -1};
//估价函数,返回当前状态与目标状态的不同位置的个数
int f(string stat)
{
int res = 0;
for(int i = 0; i < 25; i++)
{
//只需要考虑24个骑士的位置是否正确,不需要考虑*的位置,因为骑士如果都归位了,*也就归位了
if(stat[i] != target[i] && stat[i] != '*') res++;
}
return res;
}
// 从start状态开始搜索,当前搜索深度为depth,最大搜索深度为maxdepth
bool dfs(string start, int depth, int maxdepth)
{
if(depth + f(start) > maxdepth) return false; //剪枝,如果当前深度加上估价函数值大于最大深度,那么就不用继续搜索了
if(start == target) return true;
int pos = start.find('*'); //找到*的位置
int x = pos / 5, y = pos % 5; //计算*的坐标
for(int i = 0; i < 8; i++)
{
int nx = x + dx[i], ny = y + dy[i]; //计算下一个位置
if(nx < 0 || nx > 4 || ny < 0 || ny > 4) continue;
int npos = nx * 5 + ny; //计算下一个位置的一维坐标
string tmp = start;
swap(tmp[pos], tmp[npos]);
if(dfs(tmp, depth + 1, maxdepth)) return true;
}
return false;
}
int main()
{
cin >> t;
while(t--)
{
string s, line;
for(int i = 0; i < 5; i++)
{
cin >> line;
s += line;
}
int maxdepth;
for(maxdepth = 0; maxdepth <= 15; maxdepth++) //迭代加深
{
if(dfs(s, 0, maxdepth)) break;
}
if(maxdepth <= 15) cout << maxdepth << endl;
else cout << -1 << endl;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
2024-02-19 洛谷题单指南-递推与递归-P1990 覆盖墙壁
2024-02-19 洛谷题单指南-递推与递归-P1164 小A点菜