<更新提示>

<第一次更新>


<正文>

骑士精神(SCOI2005)

Description

在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位。在任何时候一个骑士都能按照骑 士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相差为2,纵坐标相差为1的格子)移动到空 位上。

给定一个初始的棋盘,怎样才能经过移动变成如下目标棋盘:

为了体现出骑士精神,他们必须以最少的步 数完成任务。

Input Format

第一行有一个正整数T(T<=10),表示一共有N组数据。接下来有T个5×5的矩阵,0表示白色骑士,1表示黑色骑士。*表示空位。两组数据之间没有空行。

Output Format

对于每组数据都输出一行。如果能在15步以内(包括15步)到达目标状态,则输出步数,否则输出-1。

Sample Input

2
10110
01*11
10111
01001
00000
01011
110*1
01110
01010
00100

Sample Output

7
-1

解析

骑士的移动方式就是中国象棋中马的移动方式,可以使用方位数组处理,我们不难到这样一个简单的\(dfs\)算法:搜索尝试对每一头马进行合法的移动,并直接对目标状态进行匹配。

由于马的数量较多,显然有很多移动是不合法的。每一次合法的移动只可能与唯一的空格交换位置,所以我们改变搜索策略,枚举空格的移动。

题目中明显给出了步数不大于十五的限制,所以我们不妨使用迭代加深的\(dfs\)算法。但是本题使用该算法仍然会超时,我们需要改进为\(IDA^*\)算法,可以如下简单地设置估价函数:

\[f(s)=\sum_{s_{i,j}\ !=goal_{i,j}}1
\]

即:当前状态与目标状态存在差异的位置个数,可以保证实际步数大于等于预估步数。

\(Code:\)

#include<bits/stdc++.h>
using namespace std;
#define mset(name,val) memset(name,val,sizeof name)
#define filein(str) freopen(str".in","r",stdin)
#define fileout(str) freopen(str".out","w",stdout)
const int T=15,INF=0x3f3f3f3f;
const int dx[]={1,-1,2,-2,1,-1,2,-2},dy[]={2,2,1,1,-2,-2,-1,-1};
const int goal[7][7]=
{
{0,0,0,0,0,0},
{0,1,1,1,1,1},
{0,0,1,1,1,1},
{0,0,0,2,1,1},
{0,0,0,0,0,1},
{0,0,0,0,0,0}
};
int Map[10][10],beginx,beginy,ans=INF,Maxdep;
inline void input(void)
{
for(int i=1;i<=5;i++)
{
for(int j=1;j<=5;j++)
{
char c=' ';
while(isspace(c))c=getchar();
if(c=='*')Map[i][j]=2,beginx=i,beginy=j;
else Map[i][j]=c-'0';
}
}
}
inline int fspend(void)
{
int res=0;
for(int i=1;i<=5;i++)
for(int j=1;j<=5;j++)
if(Map[i][j]!=goal[i][j])
res++;
return res;
}
inline bool dfs(int x,int y,int dep)
{
if(dep==Maxdep)
{
if(!fspend())ans=dep;
return true;
}
for(int i=0;i<8;i++)
{
int tx=x+dx[i],ty=y+dy[i];
if(tx<1||ty<1||tx>5||ty>5)continue;
swap(Map[x][y],Map[tx][ty]);
if(fspend()+dep<=Maxdep)
if(dfs(tx,ty,dep+1))return true;
swap(Map[tx][ty],Map[x][y]);
}
return false;
}
int main(void)
{
int T;
scanf("%d",&T);
while(T--)
{
input();
ans=0;
for(Maxdep=1;Maxdep<=15;Maxdep++)
{
if(dfs(beginx,beginy,0))
{
printf("%d\n",ans);
break;
}
}
if(!ans)printf("-1\n");
}
return 0;
}

<后记>

『骑士精神 IDA*』的更多相关文章

  1. 埃及分数&&The Rotation Game&&骑士精神——IDA*

    IDA*:非常好用的搜索,可以解决很多深度浅,但是规模大的搜索问题. 估价函数设计思路:观察一步最多能向答案靠近多少. 埃及分数 题目大意: 给出一个分数,由分子a 和分母b 构成,现在要你分解成一系 ...

  2. 【洛谷2324】[SCOI2005]骑士精神 IDA*

    [SCOI2005]骑士精神 描述 在一个\(5×5\)的棋盘上有\(12\)个白色的骑士和\(12\)个黑色的骑士, 且有一个空位.在任何时候一个骑士都能按照骑 士的走法(它可以走到和它横坐标相差为 ...

  3. [BZOJ 1085] [SCOI2005] 骑士精神 [ IDA* 搜索 ]

    题目链接 : BZOJ 1085 题目分析 : 本题中可能的状态会有 (2^24) * 25 种状态,需要使用优秀的搜索方式和一些优化技巧. 我使用的是 IDA* 搜索,从小到大枚举步数,每次 DFS ...

  4. bzoj 1085: [SCOI2005]骑士精神 IDA*

    题目链接 给一个图, 目标位置是确定的, 问你能否在15步之内达到目标位置. 因为只有15步, 所以直接ida* #include<bits/stdc++.h> using namespa ...

  5. bzoj1085 [SCOI2005]骑士精神——IDA*

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1085 搜索,IDA*,估价就是最少需要跳的步数: 代码意外地挺好写的,memcmp 用起来好 ...

  6. bzoj 1085 [SCOI2005]骑士精神——IDA*

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1085 迭代加深搜索. 估价函数是为了预计步数来剪枝,所以要优于实际步数. 没错,不是为了确定 ...

  7. 【日常学习】【IDA*】codevs2449 骑士精神题解

    题目描写叙述 Description 在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位.在不论什么时候一个骑士都能依照骑士的走法(它能够走到和它横坐标相差为1.纵坐标相差为2或 ...

  8. 1085. [SCOI2005]骑士精神【IDA※】

    Description 在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位.在任何时候一个骑士都能按照骑 士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相差为2 ...

  9. BZOJ1085:[SCOI2005]骑士精神——题解+IDA*粗略讲解

    http://www.lydsy.com/JudgeOnline/problem.php?id=1085 Description 在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空 ...

随机推荐

  1. .Karma+Jasmine+karma-coverage

    单元测试(模块测试)是开发者编写的一小段代码,用于检验被测代码的一个很小的.很明确的功能是否正确.通常而言,一个单元测试是用于判断某个特定条件(或者场景)下某个特定函数的行为. Karma是一个基于N ...

  2. PBRT笔记(14)——光线传播2:体积渲染

    传输公式 传输方程是控制光线在吸收.发射和散射辐射的介质中的行为的基本方程.它解释了第11章中描述的所有体积散射过程--吸收.发射和内.外散射.并给出了一个描述环境中辐射分布的方程.光传输方程实际上是 ...

  3. Python-list,字典,Tuple

    list:用[]包围,逗号隔开如:l = [1,2,3] 其他用法:li = ["a" ,"b" , "c", "d"] ...

  4. RSP小组——团队冲刺博客一——(领航)

    RSP小组--团队冲刺博客一--领航 冲刺日期:2018年12月10日 团队目标 经过团队讨论,我们最新确定的α版本所需实现内容如下: 1.实现游戏代码的实现 2.在Android Studio上实现 ...

  5. LOJ 6092

    这个题也很没意思 发现q那么大没有用, 不重复的询问有26*n种 所以记录一下就好了 #include<bits/stdc++.h> using namespace std; #defin ...

  6. 编程菜鸟的日记-初学尝试编程-C++ Primer Plus 第6章编程练习6

    #include <iostream> #include <string> using namespace std; const int MSIZE=100; struct j ...

  7. 原生JS面试题

    面试中遇到的原生js题总结   1.js 去重1) indexOf Array.prototype.unique = function(){ var result = []; var len = th ...

  8. 神奇高效的Linux命令行

    一.为什么要学linux命令 Linux是由命令行组成的操作系统,精髓在命令行,无论图形界面发展到什么水平,命令行方式的操作永远是不会变的.Linux命令有许多强大的功能:从简单的磁盘操作.文件存取, ...

  9. 打包java程序生成exe

    打包java程序生成exe 目标 我们知道c++的控制台程序编译运行以后就会生成一个exe可执行文件,在电脑上可以直接双击运行,但是java是跨平台的语言,编译运行以后的字节码文件.class是和平台 ...

  10. 菜鸡谈OO 第一单元总结

    “OOP永远是我的好朋友爸爸!” ——来自某无能狂怒的菜鸡 身处在OO的第一个摸鱼黄金周中的我,感觉到了巨大的满足感.如果写博客这种充满意义的事情可以代替我们亲爱的作业,那么我提议每周来两个:)下面开 ...