洛谷 P1379 八数码难题
Description
Solution
似乎各种做法都可以过,我写的 IDA∗。
很明显,乐观估价函数即为当前棋盘与目标棋盘上不同的数字个数。
所以直接枚举深搜层数,然后搜索即可。
IDA∗ 的主要难度就在乐观估价函数上,这个弄明白之后,就很简单了。
然后这个写法上面还有一点问题,总之背过板子就好。
另外,还要加一个剪枝:不能走向上一个格子。
简单来说就是不能来回走。这个把方向数组构造一下,然后判断一下即可,见代码。
其他的就没什么了。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
int a[5][5];
int b[4][4] = {
0, 0, 0, 0,
0, 1, 2, 3,
0, 8, 0, 4,
0, 7, 6, 5
};
int tmp, ans, flag;
int dx[4] = {-1, 0, 0, 1};
int dy[4] = {0, -1, 1, 0};
//上左右下
inline int check(){
int res = 0;
for(int i = 1; i <= 3; i++)
for(int j = 1; j <= 3; j++)
res += (a[i][j] != b[i][j]);
return res;
}
inline void dfs(int x, int y, int step, int pre){
if(step == tmp){
if(!check()) flag = 1;
return;
}
if(flag) return;
for(int i = 0; i < 4; i++){
int mx = x + dx[i];
int my = y + dy[i];
if(mx < 1 || mx > 3 || my < 1 || my > 3 || i + pre == 3) continue;
swap(a[x][y], a[mx][my]);
if(!flag && check() + step <= tmp) dfs(mx, my, step + 1, i);
swap(a[x][y], a[mx][my]);
}
}
int main(){
int x, y;
for(int i = 1; i <= 3; i++)
for(int j = 1; j <= 3; j++){
char c = getchar();
if(c == '0') x = i, y = j;
a[i][j] = c - '0';
}
if(!check()){
puts("0");
return 0;
}
for(tmp = 1; ; tmp++){
dfs(x, y, 0, -1);
if(flag){
printf("%d\n", tmp);
return 0;
}
}
return 0;
}
End
本文作者:xixike
本文链接:https://www.cnblogs.com/xixike/p/15381326.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
分类:
OJ——洛谷
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 为DeepSeek添加本地知识库
· .NET程序员AI开发基座:Microsoft.Extensions.AI
· 精选4款基于.NET开源、功能强大的通讯调试工具
· 数据不出内网:基于Ollama+OneAPI构建企业专属DeepSeek智能中台
· 大模型工具KTransformer的安装