IDA*算法——骑士精神
例题
骑士精神
Description
在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位。在任何时候一个骑士都能按照骑士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相差为2,纵坐标相差为1的格子)移动到空位上。
给定一个初始的棋盘,怎样才能经过移动变成如下目标棋盘:
为了体现出骑士精神,他们必须以最少的步数完成任务。
Input
第一行有一个正整数T(T<=10),表示一共有N组数据。接下来有T个5×5的矩阵,0表示白色骑士,1表示黑色骑士,*表示空位。两组数据之间没有空行。
Output
对于每组数据都输出一行。如果能在15步以内(包括15步)到达目标状态,则输出步数,否则输出-1。
Sample Input
2
10110
01*11
10111
01001
00000
01011
110*1
01110
01010
00100
Sample Output
7
-1
样例中第二个数据的初始情况对应该图:
做法
这题的状态共有3^25,遍历完所有状态的时间则是8^15。
考虑用IDA*(貌似有其它做法)
举个简单的例子(不是指这题):
如果用DFS,搜得过深却容易找不到解。所以应用BFS或IDDFS(迭代加深搜索)。
但是BFS有一个缺点,就是空间大。
因此,结合DFS和BFS,就有了IDDFS。
就是先搜深度为0的节点,再搜深度为1的节点、2的节点……直到搜出解。
为什么不用二分?因为节点的数量是指数级增长的,这样可能搜出很多无意义的情况。
IDDFS的缺点:搜过的点会再搜。
然而这样时间还会爆掉。我们可以用启发式搜索中的IDA*,设h(估价函数)为当前这个状态,没回到应该回到位置上的点的个数-1。为什么要-1?对于这题,若走k次,则最多更新k+1个点(原因显然,自己思考);反过来就是说,若想要更新k个节点,则最少走k-1次。所以,h要-1。这样就保证了h(i)<=h*(i)(估计距离<=实际距离),保证了答案的正确性。只需利用h进行剪枝即可。
代码实现(C++)
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
char map[7][7];//地图
char tar[7][7]={{},{0,'1','1','1','1','1'},{0,'0','1','1','1','1'},{0,'0','0','*','1','1'},{0,'0','0','0','0','1'},{0,'0','0','0','0','0'}};//目标状态
int fx[9]={0,-1,-1, 1, 1,-2,-2, 2, 2};
int fy[9]={0,-2, 2,-2, 2,-1, 1,-1, 1};
bool IDA_star(int,int,int,int,int);
int main()
{
int T;
scanf("%d",&T);
getchar();//使用getchar()的原因只是方便读入
int i,j,h,x,y;
while (T--)
{
for (i=1;i<=5;++i)
{
for (j=1;j<=5;++j)
if ((map[i][j]=getchar())=='*')
{
x=i;
y=j;
}
getchar();
}
h=0;
for (i=1;i<=5;++i)
for (j=1;j<=5;++j)
h+=(map[i][j]!=tar[i][j]);//统计不在位置上的点
for (i=0;i<=15;++i)
if (IDA_star(0,h-1,i,x,y))//迭代加深(h-1的原因见上面)
{
printf("%d\n",i);
break;
}
if (i>15)
printf("-1\n");
}
}
bool IDA_star(int g,int h,int lim,int x,int y)//g为现在的步数,h为估价函数,lim为限制深度,(x,y)为'*'的坐标(x行y列)
{
if (g+h>lim)//剪枝,若无论如何不能在限制时间内达到
return 0;
if (g==lim)
return 1;
int i,tx,ty;
char tmp;
for (i=1;i<=8;++i)
{
tx=x+fx[i];
ty=y+fy[i];
if (1<=tx && tx<=5 && 1<=ty && ty<=5)
{
tmp=0;
tmp-=(map[x][y]!=tar[x][y])+(map[tx][ty]!=tar[tx][ty]);//将两个点对估价函数的影响减去
swap(map[x][y],map[tx][ty]);//交换
tmp+=(map[x][y]!=tar[x][y])+(map[tx][ty]!=tar[tx][ty]);//将两个交换后的点对估价函数的影响加上
if (IDA_star(g+1,h+tmp,lim,tx,ty))
return 1;
swap(map[x][y],map[tx][ty]);
}
}
return 0;
}
IDA*算法——骑士精神的更多相关文章
- A*算法详解 BZOJ 1085骑士精神
转载1:A*算法入门 http://www.cppblog.com/mythit/archive/2009/04/19/80492.aspx 在看下面这篇文章之前,先介绍几个理论知识,有助于理解A*算 ...
- 『骑士精神 IDA*』
骑士精神(SCOI2005) Description 在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位.在任何时候一个骑士都能按照骑 士的走法(它可以走到和它横坐标相差为1,纵 ...
- 【日常学习】【IDA*】codevs2449 骑士精神题解
题目描写叙述 Description 在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位.在不论什么时候一个骑士都能依照骑士的走法(它能够走到和它横坐标相差为1.纵坐标相差为2或 ...
- 1085. [SCOI2005]骑士精神【IDA※】
Description 在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位.在任何时候一个骑士都能按照骑 士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相差为2 ...
- 埃及分数&&The Rotation Game&&骑士精神——IDA*
IDA*:非常好用的搜索,可以解决很多深度浅,但是规模大的搜索问题. 估价函数设计思路:观察一步最多能向答案靠近多少. 埃及分数 题目大意: 给出一个分数,由分子a 和分母b 构成,现在要你分解成一系 ...
- BZOJ1085:[SCOI2005]骑士精神——题解+IDA*粗略讲解
http://www.lydsy.com/JudgeOnline/problem.php?id=1085 Description 在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空 ...
- 【洛谷2324】[SCOI2005]骑士精神 IDA*
[SCOI2005]骑士精神 描述 在一个\(5×5\)的棋盘上有\(12\)个白色的骑士和\(12\)个黑色的骑士, 且有一个空位.在任何时候一个骑士都能按照骑 士的走法(它可以走到和它横坐标相差为 ...
- BZOJ1085: [SCOI2005]骑士精神 [迭代加深搜索 IDA*]
1085: [SCOI2005]骑士精神 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1800 Solved: 984[Submit][Statu ...
- 【洛谷】2324:[SCOI2005]骑士精神【IDA*】
P2324 [SCOI2005]骑士精神 题目描述 输入输出格式 输入格式: 第一行有一个正整数T(T<=10),表示一共有N组数据.接下来有T个5×5的矩阵,0表示白色骑士,1表示黑色骑士,* ...
随机推荐
- PMP-49个过程快速导览
启动过程组 名正言顺 人鬼佛神 01 -4.1制定项目章程 -授权PM,启动项目 ● 编写一份正式批准项目并授权项目经理在项目活动中使用组织资源的文件的过程 ● 明确项目与组织战略目标之间的联系,确立 ...
- 6. 第一个jmeter脚本开发-测试百度首页
需求:可以承受5个用户同时访问百度解题思路:我们可以从这短短的一句话中提取3个点:同时.5个并发.百度服务器解题方法:方法一:录制请求录制方法会在下一篇进行讲解,本篇不做过多介绍. 方法二:自定义添加 ...
- Ctrl快捷键
Ctrl + a - Jump to the start of the lineCtrl + b - Move back a charCtrl + c - Terminate the command ...
- Git的故事
目录 Git Git的概念 Git的安装 Git的配置 Git的指令 Git Git的概念 首先我们要知道git是什么,最根本的概念是版本控制,顾名思义,就是git可以帮助我们控制自己写的代码或者文档 ...
- sklearn中模型评估和预测
一.模型验证方法如下: 通过交叉验证得分:model_sleection.cross_val_score(estimator,X) 对每个输入数据点产生交叉验证估计:model_selection.c ...
- 《转》python对象
http://www.cnblogs.com/BeginMan/p/3160044.html 一.学习目录 1.pyhton对象 2.python类型 3.类型操作符与内建函数 4.类型工厂函数 5. ...
- cors是什么?django中怎么解决这个问题?
跨域资源共享(CORS) 是一种机制. 当一个资源从与该资源本身所在的服务器不同的域.协议或端口请求一个资源时,资源会发起一个跨域 HTTP 请求.(CORS是一种可以让你实现跨站点请求并同时阻止恶意 ...
- 17-Ubuntu-文件和目录命令-切换目录-相对路径和绝对路径
1.相对路径: 在输入路径时,最前面不是/或者~,表示相对当前目录所在的目录位置. 例:当前桌面目录下,通过相对路径切换到桌面目录下的Entertainment目录 2.绝对路径: 在输入路径时,最前 ...
- libgdx 启动者(个人翻译,还请不吝赐教)类和配置
本文章翻译自libGDX官方wiki,.转载请注明出处:http://blog.csdn.net/kent_todo/article/details/37942047 libGDX官方网址:http: ...
- 关于 wpf 的ICommand 的 CanExecute CanExecuteChanged func action的认识
关于 wpf 的ICommand 的 CanExecute CanExecuteChanged func action的认识