[A*,启发式搜索] [SCOI2005] 骑士精神
链接:https://ac.nowcoder.com/acm/problem/20247
来源:牛客网
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述

输入描述:
第一行有一个正整数T(T ≤ 10),表示一共有N组数据
接下来有T个5×5的矩阵,0表示白色骑士,1表示黑色骑 士,*表示空位。两组数据之间没有空行。
输出描述:
对于每组数据都输出一行。如果能在15步以内(包括15步)到达目标状态,则输出步数,否则输出-1。
输出
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] 骑士精神的更多相关文章
- BZOJ 1085 [SCOI2005]骑士精神 【A*启发式搜索】
1085: [SCOI2005]骑士精神 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 2838 Solved: 1663 [Submit][St ...
- BZOJ1085: [SCOI2005]骑士精神 [迭代加深搜索 IDA*]
1085: [SCOI2005]骑士精神 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1800 Solved: 984[Submit][Statu ...
- 【bzoj1085】[SCOI2005]骑士精神
1085: [SCOI2005]骑士精神 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1757 Solved: 961[Submit][Statu ...
- BZOJ 1085: [SCOI2005]骑士精神( IDDFS + A* )
一开始写了个 BFS 然后就 T 了... 这道题是迭代加深搜索 + A* -------------------------------------------------------------- ...
- BZOJ_1085_[SCOI2005]骑士精神_IDDFS
BZOJ_1085_[SCOI2005]骑士精神_DFS Description 在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位.在任何时候一个骑士都能按照骑 士的走法(它可 ...
- [luogu P2324] [SCOI2005]骑士精神
[luogu P2324] [SCOI2005]骑士精神 题目描述 输入输出格式 输入格式: 第一行有一个正整数T(T<=10),表示一共有N组数据.接下来有T个5×5的矩阵,0表示白色骑士,1 ...
- 【洛谷】2324:[SCOI2005]骑士精神【IDA*】
P2324 [SCOI2005]骑士精神 题目描述 输入输出格式 输入格式: 第一行有一个正整数T(T<=10),表示一共有N组数据.接下来有T个5×5的矩阵,0表示白色骑士,1表示黑色骑士,* ...
- BZOJ1085 SCOI2005 骑士精神【IDA* 启发式迭代加深】
BZOJ1085 SCOI2005 骑士精神 Description 在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位.在任何时候一个骑士都能按照骑士的走法(它可以走到和它横坐 ...
- 洛谷 P2324 [SCOI2005]骑士精神 解题报告
P2324 [SCOI2005]骑士精神 题目描述 输入输出格式 输入格式: 第一行有一个正整数T(T<=10),表示一共有N组数据.接下来有T个5×5的矩阵,0表示白色骑士,1表示黑色骑士,* ...
随机推荐
- 解密JDK8 枚举
写一个枚举类 1 2 3 4 5 6 public enum Season { SPRING, SUMMER, AUTUMN, WINTER } 然后我们使用javac编译上面的类,得到class文件 ...
- ES6中的数组
数组是js中很重要的数据类型,虽然在 ES5 中,关于数组的方法和属性很多.但为了更加简洁.高效的操作数组,ES6 中又在数组原型上和实例上新增了一些方法. 一.Array方法 1.1 Array.f ...
- hadoop地址配置、内存配置、守护进程设置、环境设置
1.1 hadoop配置 hadoop配置文件在安装包的etc/hadoop目录下,但是为了方便升级,配置不被覆盖一般放在其他地方,并用环境变量HADOOP_CONF_DIR指定目录. 1.1.1 ...
- unittest实战(一):用例框架
import unittest class forTest0(unittest.TestCase): @classmethod def setUpClass(cls) -> None: prin ...
- 前端每日实战:26# 视频演示如何用不到 50 行 CSS 代码,创作按钮被从纸上掀起的立体效果
效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/KRbXGe 可交互视频教程 此视频 ...
- Yuchuan_Linux_C编程之九目录操作相关函数
一.整体大纲 二.相关函数 1. getcwd 函数作用:获取当前目录 头文件 #include <unistd.h> 函数原型 char *getcwd(char *buf, size_ ...
- 必备技能七、Vuex
这段时间一直在用vue写项目,vuex在项目中也会依葫芦画瓢使用,但是总有一种朦朦胧胧的感觉.于是决定彻底搞懂它. 看了一下午的官方文档,以及资料,才发现vuex so easy! 作为一个圈子中的人 ...
- js原型继承题目
var F = function(){}; Object.prototype.a = function(){}; Function.prototype.b = function(){}; var f ...
- 【沫沫金】使用Serv-U FTP服务,搭建文件服务器
内网文件服务器安装Serv-U FTP 链接: https://pan.baidu.com/s/1G51D1enLqZCUhnprnjAITw 提取码: snah Java Web工程,引入 comm ...
- pikachu——暴力破解
前述: 前面学习了sqli-labs 和 DVWA,也算是初步涉足了web漏洞,了解了一些web漏洞的知识.所以在pikachu上面,会更加仔细认真,把前面没有介绍到的知识点和我一边学习到的新知识再补 ...