链接:https://ac.nowcoder.com/acm/problem/20247
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位。在任何时候一个骑士都能按照骑士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相差为2,纵坐标相差为1的格子)移动到空 位上。 
给定一个初始的棋盘,怎样才能经过移动变成如下目标棋盘: 为了体现出骑士精神,他们必须以最少的步数完成任务。
 

输入描述:

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

输出描述:

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

输入

复制

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

输出

复制

7
-1

题意:

有一个5*5的棋盘,上面放了24个骑士棋子,和一个空位,每个棋子可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相差为2,纵坐标相差为1的空位
题目给了一个目标状态,问现在的状态转移到目标状态最少步数是多少,如果最少步数超过15则输出-1

思路:

模拟了第一个样例发现,棋盘中有7个与目标状态不同的骑士,而最少步数为7,也就是说最少步数最少为初始状态中有多少与标准不同的骑士的个数,这样刚好不会浪费格子,
所以枚举最少步数,从空格开始搜索,每次搜索预估代价,当前局面最小移动步数=现在有多少与标准不同的骑士的个数,
步数+预估代价>限制时(到14步时可能会有2个棋子不同但只要一步就能纠正这2个棋子,也就是步数+预估代价==16时是最大可接受范围,所以限制要设为大于等于16的数)或步数大于等于最小可行步数时返回,如果现在局面和标准相同则记录答案(只有步数小于最小可行步数时才会更新答案),
如果搜索越界或现在的操作和上一个操作互逆(如果当前操作和上一个操作互逆却继续搜索那不就返回去了吗)则跳过,
否则交换搜索的棋子和当前棋子并搜索交换棋子的那个位置,且回溯时还原局面

 #include<bits/stdc++.h>
using namespace std;
const int amn=,inf=0x3f3f3f3f;
int a[amn][amn],
mp[amn][amn]={
{,,,,},
{,,,,},
{,,,,},
{,,,,},
{,,,,}
}, ///0^1=1,1^1=0,2^1=3,3^1=2,4^1=5,5^1=4...
dt[][]={ ///方向储存时互逆操作相邻,这样就可以通过i^1,判断上一个操作是否和当前操作互逆
{-,-},{,},
{-,-},{,},
{,-},{-,},
{,-},{-,}
};
int ans,lim;
int hst(){ ///预估代价,最小移动步数=现在有多少与标准不同的骑士的个数
int h=;
for(int i=;i<;i++)
for(int j=;j<;j++)
h+=(a[i][j]!=mp[i][j]); ///判断现在有多少与标准不同的骑士
return h;
}
void dfs(int x,int y,int step,int last){
int h=hst();
if(step+h>lim||step>=ans)return; ///步数+预估代价>限制时(到14步时可能会有2个棋子不同但只要一步就能纠正这2个棋子,也就是步数+预估代价==16时是最大可接受范围,所以限制要设为大于等于16的数)或步数大于等于最小可行步数时返回
if(h==){ ///如果现在局面和标准相同则记录答案(只有步数小于最小可行步数时才会更新答案)
ans=step;
return ;
}
for(int i=;i<;i++){
int dx=x+dt[i][],dy=y+dt[i][];
if(dx<||dx>||dy<||dy>||(i^)==last)continue; ///如果搜索越界或现在的操作和上一个操作互逆(如果当前操作和上一个操作互逆却继续搜索那不就返回去了吗)则跳过
swap(a[dx][dy],a[x][y]); ///交换
dfs(dx,dy,step+,i);
swap(a[dx][dy],a[x][y]); ///回溯时还原局面
}
}
int main(){
int T,stx,sty;
char in;
scanf("%d",&T);
getchar();
while(T--){
for(int i=;i<;i++){
for(int j=;j<;j++){
scanf("%c",&in);
if(in=='')
a[i][j]=;
else if(in=='')
a[i][j]=;
else
a[i][j]=,stx=i,sty=j;
}
getchar();
}
ans=inf;
int h=hst();
for(int i=h;i<=;i++){ ///枚举限制,最小限制从现在有多少与标准不同的骑士的个数开始,到一个大于等于16的数(太大了会超时),
到14步时可能会有2个棋子不同但只要一步就能纠正这2个棋子,也就是步数+预估代价==16时是最大可接受范围,所以限制要设为大于等于16的数
lim=i;
dfs(stx,sty,,inf);
}
printf("%d\n",ans>?-:ans);
}
}
/**
有一个5*5的棋盘,上面放了24个骑士棋子,和一个空位,每个棋子可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相差为2,纵坐标相差为1的空位
题目给了一个目标状态,问现在的状态转移到目标状态最少步数是多少,如果最少步数超过15则输出-1
模拟了第一个样例发现,棋盘中有7个与目标状态不同的骑士,而最少步数为7,也就是说最少步数最少为初始状态中有多少与标准不同的骑士的个数,这样刚好不会浪费格子,
所以枚举最少步数,从空格开始搜索,每次搜索预估代价,当前局面最小移动步数=现在有多少与标准不同的骑士的个数,
步数-1+预估代价>限制时(到14步时可能会有2个棋子不同但只要一步就能纠正这2个棋子,也就是步数+预估代价==16时是最大可接受范围,所以限制要设为大于等于16的数)或步数大于等于最小可行步数时返回,如果现在局面和标准相同则记录答案(只有步数小于最小可行步数时才会更新答案),
如果搜索越界或现在的操作和上一个操作互逆(如果当前操作和上一个操作互逆却继续搜索那不就返回去了吗)则跳过,
否则交换搜索的棋子和当前棋子并搜索交换棋子的那个位置,且回溯时还原局面
**/

[A*,启发式搜索] [SCOI2005] 骑士精神的更多相关文章

  1. BZOJ 1085 [SCOI2005]骑士精神 【A*启发式搜索】

    1085: [SCOI2005]骑士精神 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 2838  Solved: 1663 [Submit][St ...

  2. BZOJ1085: [SCOI2005]骑士精神 [迭代加深搜索 IDA*]

    1085: [SCOI2005]骑士精神 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1800  Solved: 984[Submit][Statu ...

  3. 【bzoj1085】[SCOI2005]骑士精神

    1085: [SCOI2005]骑士精神 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1757  Solved: 961[Submit][Statu ...

  4. BZOJ 1085: [SCOI2005]骑士精神( IDDFS + A* )

    一开始写了个 BFS 然后就 T 了... 这道题是迭代加深搜索 + A* -------------------------------------------------------------- ...

  5. BZOJ_1085_[SCOI2005]骑士精神_IDDFS

    BZOJ_1085_[SCOI2005]骑士精神_DFS Description 在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位.在任何时候一个骑士都能按照骑 士的走法(它可 ...

  6. [luogu P2324] [SCOI2005]骑士精神

    [luogu P2324] [SCOI2005]骑士精神 题目描述 输入输出格式 输入格式: 第一行有一个正整数T(T<=10),表示一共有N组数据.接下来有T个5×5的矩阵,0表示白色骑士,1 ...

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

    P2324 [SCOI2005]骑士精神 题目描述 输入输出格式 输入格式: 第一行有一个正整数T(T<=10),表示一共有N组数据.接下来有T个5×5的矩阵,0表示白色骑士,1表示黑色骑士,* ...

  8. BZOJ1085 SCOI2005 骑士精神【IDA* 启发式迭代加深】

    BZOJ1085 SCOI2005 骑士精神 Description 在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位.在任何时候一个骑士都能按照骑士的走法(它可以走到和它横坐 ...

  9. 洛谷 P2324 [SCOI2005]骑士精神 解题报告

    P2324 [SCOI2005]骑士精神 题目描述 输入输出格式 输入格式: 第一行有一个正整数T(T<=10),表示一共有N组数据.接下来有T个5×5的矩阵,0表示白色骑士,1表示黑色骑士,* ...

随机推荐

  1. 自动化移动安全渗透测试框架:Mobile Security Framework

    自动化移动安全渗透测试框架:Mobile Security Framework 译/Sphinx  测试开发社区  7月3日 Mobile Security Framework (移动安全框架) 是一 ...

  2. 仿豆瓣首页弹性滑动控件|Axlchen's blog

    逛豆瓣的时候看到了这样的控件,觉得挺有趣,遂模仿之 先看看原版的效果 再看看模仿的效果 分析 控件结构分析 由于*ScrollView只能有一个child view,所以整个child view的结构 ...

  3. ECMA5中定义的对象属性特性和方法

    ECMA5规定了只有内部才有的特性,描述了属性的各种特征,这些特性用于实现JavaScript引擎,因此在Js中不能直接访问他们.为了标识特性,我们一般会他们放入两对方括号中. ECMAScript中 ...

  4. -scp Linux之间复制文件和目录

    scp 简介 scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的.可能会稍微影响一下速 ...

  5. 机器学习- RNN以及LSTM的原理分析

    概述 RNN是递归神经网络,它提供了一种解决深度学习的另一个思路,那就是每一步的输出不仅仅跟当前这一步的输入有关,而且还跟前面和后面的输入输出有关,尤其是在一些NLP的应用中,经常会用到,例如在NLP ...

  6. vue-cli “从入门到放弃”

    主要作用:目录结构.本地调试.代码部署.热加载.单元测试 在如今前端技术飞速发展的时代,angular.js.vue.js 和 react.js 作为前端框架已经呈现出了三国鼎立的局面.作为国人若你不 ...

  7. php表单提交后再后退 内容则默认清空的解决方法

    转载原文地址: http://www.jquerycn.cn/a_14422 在session_start()之后,字符输出之前加上header("Cache-control: privat ...

  8. 前后端分离下的跨域CAS请求

    最重要的两点: ajax请求跨域的时候,默认不会携带cookie. 请求分为普通请求(HttpRequest)和Ajax请求(XMLHttpRequest) 先屡一下跨域CAS认证的流程: 前端发起a ...

  9. ELK springboot日志收集

    一.安装elasticsearch 可以查看前篇博客 elasticsearch安装.elasticsearch-head 安装 二.安装 配置 logstash 1.安装logstash 下载地址: ...

  10. nsq 初学使用日记

    win下更加直观一些,所以不使用liunx 第一步下载 nsq 下载地址 https://github.com/nsqio/nsq.git 使用git clone或者go get 下载下来 第二部 编 ...