洛谷 - P2324 - 骑士精神 - A*搜索
为什么估价是16,因为最后一步复原空格可以恢复两个位置,当然设成17、18都可以。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct State {
char g[5][6]; //矩阵的状态,0是白马,1是黑马,规定空格是*
int hstep; //step+估价函数,至少需要的步数
State() {}
int h(); //估价函数h,为未归位的骑士数
void move_to(int id,int step); //尝试移动状态加入优先队列
bool operator==(const State& s)const {
//无序map
for(int i=0; i<5; i++)
for(int j=0; j<5; j++)
if(g[i][j]!=s.g[i][j])
return false;
return true;
}
bool operator<(const State& s)const {
//最大堆
return hstep>s.hstep;
}
} s_state,t_state;
struct State_Hash {
size_t operator()(const State&t)const {
int id=0;
for(int i=0; i<5; i++)
for(int j=0; j<5; j++)
id=(id<<1)+(t.g[i][j]-'0');
return id;
}
};
int State::h() {
//估价函数,因为每次移动的是空格
int res=0;
for(int i=0; i<5; i++)
for(int j=0; j<5; j++)
if(g[i][j]!=t_state.g[i][j])
res++;
return res;
}
//vis从起点开始找到的状态
unordered_map<State,int,State_Hash> vis;
priority_queue<State> pq;
int dx[]= {2,1,-1,-2,-2,-1,1,2};
int dy[]= {1,2,2,1,-1,-2,-2,-1};
void State::move_to(int id,int step) {
//空格向id方向移动
int ox=-1;
int oy=-1;
for(int i=0; i<5; i++) {
for(int j=0; j<5; j++) {
if(g[i][j]=='*') {
ox=i,oy=j;
break;
}
}
}
int nx=ox+dx[id];
int ny=oy+dy[id];
//越界
if(nx<0||ny<0||nx>4||ny>4)
return;
State res=*this;
swap(res.g[ox][oy],res.g[nx][ny]);
res.hstep=step+1+res.h();
if(hstep>16)
return;
if(vis.count(res)) {
return;
} else {
vis[res]=step+1;
pq.push(res);
}
}
//单向A*搜索
bool A_star() {
vis.clear();
while(!pq.empty())
pq.pop();
vis[s_state]=0;
pq.push(s_state);
while(!pq.empty()) {
State curstate=pq.top();
pq.pop();
int curstep=vis[curstate];
for(int i=0; i<8; i++)
curstate.move_to(i,curstep);
if(vis.count(t_state))
return true;
}
return false;
}
int main() {
#ifdef Yinku
freopen("Yinku.in","r",stdin);
#endif // Yinku
strcpy(t_state.g[0],"11111");
strcpy(t_state.g[1],"01111");
strcpy(t_state.g[2],"00*11");
strcpy(t_state.g[3],"00001");
strcpy(t_state.g[4],"00000");;
int T;
scanf("%d",&T);
while(T--) {
for(int i=0; i<5; i++)
scanf("%s",s_state.g[i]);
if(A_star()) {
int ans=vis[t_state];
printf("%d\n",ans>15?-1:ans);
} else {
puts("-1");
}
}
return 0;
}
洛谷 - P2324 - 骑士精神 - A*搜索的更多相关文章
- 洛谷 P2324 [SCOI2005]骑士精神 解题报告
P2324 [SCOI2005]骑士精神 题目描述 输入输出格式 输入格式: 第一行有一个正整数T(T<=10),表示一共有N组数据.接下来有T个5×5的矩阵,0表示白色骑士,1表示黑色骑士,* ...
- 【洛谷P2324】[SCOI2005]骑士精神
骑士精神 题目链接 #include<iostream> #include<cstdio> using namespace std; int t,MAXD,sx,sy; ][] ...
- 【题解】洛谷P1120 小木棍(搜索+剪枝+卡常)
洛谷P1120:https://www.luogu.org/problemnew/show/P1120 思路 明显是搜索题嘛 但是这数据增强不是一星半点呐 我们需要N多的剪枝 PS:需要先删去超出50 ...
- 【BZOJ1085】【SCOI2005】骑士精神 [A*搜索]
骑士精神 Time Limit: 10 Sec Memory Limit: 162 MB[Submit][Status][Discuss] Description 在一个5×5的棋盘上有12个白色的 ...
- bzoj1085骑士精神(搜索)
1085: [SCOI2005]骑士精神 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1893 Solved: 1051 Description ...
- 【题解】洛谷P1731 [NOI1999] 生日蛋糕(搜索+剪枝)
洛谷P1731:https://www.luogu.org/problemnew/show/P1731 思路 三重剪枝 当前表面积+下一层表面积如果超过最优值就退出 当前体积+下一层体积如果超过总体积 ...
- B1085 [SCOI2005]骑士精神 A*搜索
其实就是一个爆搜加剪枝.直接爆搜肯定不行,而A*算法则是想假如剩下都是最优的话,我当前步数还是不足以达到这个状态,那么就直接返回,因为最优状态也无法做到显然不行. 这道题可以用A*最主要就是因为有15 ...
- 和小哥哥一起刷洛谷(5) 图论之深度优先搜索DFS
关于dfs dfs伪代码: void dfs(s){ for(int i=0;i<s的出度;i++){ if(used[i]为真) continue; used[i]=1; dfs(i); } ...
- 和小哥哥一起刷洛谷(4) 图论之广度优先搜索BFS
关于bfs: 你怎么会连这个都不知道!!!自己好好谷歌一下!!!(其实我也刚学) bfs伪代码: while(队列非空){ 取出队首元素u; 弹出队首元素; u染色为黑色; for(int i=0;i ...
随机推荐
- HNOI2017
本蒟蒻表示终于把$HNOI2017$全AC了... 万岁! 附上各个题的题解: $DAY1$: $T1$: BZOJ4825: [Hnoi2017]单旋 $T2$: BZOJ4826: [Hnoi20 ...
- PHP通过session id 实现session共享和登录验证的代码
先说说,这个机制的用途吧,到现在为止战地知道这个机制有两个方面的用途: 首先,多服务器共享session问题,这个大家应该都能够理解的,当一个网站的用户量过大,就会使用服务器集群,例如专门有一个登录用 ...
- 【Java 语言生态篇】Junit 测试单元
01 概述 JUnit是一个由 Erich Gamma 和 Kent Beck 编写的一个回归测试框架(regression testing framework).Junit测试是白盒测试.JUn ...
- bind、call、apply的区别与实现原理
1.简单说一下bind.call.apply的区别 三者都是用于改变函数体内this的指向,但是bind与apply和call的最大的区别是:bind不会立即调用,而是返回一个新函数,称为绑定函数,其 ...
- git创建项目的两种方式
场景1: 将本地内容推送给远程库 1.创建版本库 git init 将此目录转换为git可管理的仓库 git config --global user.name "xx" 或 gi ...
- HDU3247 Resource Archiver —— AC自动机 + BFS最短路 + 状压DP
题目链接:https://vjudge.net/problem/HDU-3247 Resource Archiver Time Limit: 20000/10000 MS (Java/Others) ...
- eclipse批量修改package、import中的包名
问题:想把以前开发的包,用到新项目中,怎么操作呢? 解决方案: 把文件夹复制到新项目包中,同时需要更改很多package.import中的包名第一步:打开一个java文件,选中要替换的字段: 第二步: ...
- css3线性渐变兼容
火狐浏览器: background:-moz-linear-gradient(top, red, rgba(0, 0, 255, 0.5)); 谷歌: .l6{background: -webkit- ...
- UTCformat 转换UTC时间并格式化成本地时间
/** * UTCformat 转换UTC时间并格式化成本地时间 * @param {string} utc */ UTCformat (utc) { var date = new Date(utc) ...
- 理解YOLOv2训练过程中输出参数含义
原英文地址: https://timebutt.github.io/static/understanding-yolov2-training-output/ 最近有人问起在YOLOv2训练过程中输出在 ...