【启发式搜索】【A*算法】hdu6171 Admiral

一个舰队的目标状态如上图。红色是旗舰。然后给你初始局面,每一次决策可以把旗舰和其上一层或下一层的两个相邻的进行交换。如果能在20步内出解的话,输出最小步数;否则输出“too difficult”。
把每个方块当成0~5的数,整个状态正好可以压缩成1个21位的6进制数,恰好可以用long long存下,可以用set / 哈希表存储。
定义估价函数f(S)表示局面S的每个格子所在层数与它的目标状态所在层的差的绝对值之和。
这样每一次移动最多使这个值减小2,如果这个值大于(20-已经走的步数)*2,则剪枝。
#include<cstdio>
#include<algorithm>
#include<queue>
#include<set>
using namespace std;
const int dx[]={1,1,-1,-1},dy[]={0,1,0,-1};
typedef long long ll;
typedef pair<int,int> Point;
set<ll>S;
int T;
struct Node{
ll st;
Point pos;
int d;
Node(){}
Node(const ll &st,const Point &pos,const int &d){
this->st=st;
this->pos=pos;
this->d=d;
}
};
int ceng[25];
int Abs(int x){
return x<0 ? (-x) : x;
}
int calc(ll x){
int res=0;
for(int i=0;i<=20;++i){
res+=Abs((int)(x%6ll)-ceng[i]);
x/=6;
}
return res;
}
queue<Node>q;
int wei[8][8];
ll pw[30];
int main(){
int x;
// freopen("1001.in","r",stdin);
// freopen("1001.out","w",stdout);
pw[0]=1;
for(int i=1;i<=20;++i){
pw[i]=pw[i-1]*6ll;
}
scanf("%d",&T);
ceng[0]=ceng[1]=ceng[2]=ceng[3]=ceng[4]=ceng[5]=5;
ceng[6]=ceng[7]=ceng[8]=ceng[9]=ceng[10]=4;
ceng[11]=ceng[12]=ceng[13]=ceng[14]=3;
ceng[15]=ceng[16]=ceng[17]=2;
ceng[18]=ceng[19]=1;
ceng[20]=0;
int pen=20;
for(int i=0;i<6;++i){
for(int j=0;j<=i;++j){
wei[i][j]=pen;
--pen;
}
}
ll goal=0;
for(int i=0;i<6;++i){
for(int j=0;j<=i;++j){
goal=goal*6ll+(ll)i;
}
}
for(;T;--T){
S.clear();
ll st=0;
Point stapos;
for(int i=0;i<6;++i){
for(int j=0;j<=i;++j){
scanf("%d",&x);
if(x==0){
stapos=Point(i,j);
}
st=st*6ll+(ll)x;
}
}
if(st==goal){
puts("0");
continue;
}
S.insert(st);
bool ok=0;
while(!q.empty()){
q.pop();
}
q.push(Node(st,stapos,0));
while(!q.empty()){
Node U=q.front(); q.pop();
// ll now=U.st;
// for(int i=0;i<6;++i){
// for(int j=0;j<=i;++j){
// printf("%I64d ",now/pw[wei[i][j]]%6ll);
// }
// puts("");
// }
// puts("");
if(U.d>=20){
continue;
}
for(int i=0;i<4;++i){
int tx=U.pos.first+dx[i],ty=U.pos.second+dy[i];
if(tx>=0 && tx<=5 && ty>=0 && ty<=tx){
ll nextst=U.st-pw[wei[tx][ty]]*(U.st/pw[wei[tx][ty]]%6ll);
nextst+=pw[wei[U.pos.first][U.pos.second]]*(U.st/pw[wei[tx][ty]]%6ll);
int tmp=calc(nextst);
if(S.find(nextst)==S.end() && tmp<=(20-(U.d+1))*2){
if(nextst==goal){
ok=1;
printf("%d\n",U.d+1);
break;
}
S.insert(nextst);
q.push(Node(nextst,Point(tx,ty),U.d+1));
}
}
}
if(ok){
break;
}
}
if(!ok){
puts("too difficult");
}
}
return 0;
}
【启发式搜索】【A*算法】hdu6171 Admiral的更多相关文章
- 启发式搜索A*算法
A* 寻路算法 (2011-02-15 10:53:11) 转载▼ 标签: 游戏 分类: 算法 概述 虽然掌握了 A* 算法的人认为它容易,但是对于初学者来说, A* 算法还是很复杂的. 搜索区域(T ...
- 启发式搜索——A*算法
启发式搜索 启发式搜索是一种对搜索到的每一个位置进行评估,然后从评估的最优位置进行搜索直到目的地, 由于搜索时对每一个位置的评估是基于直观或经验的所有叫启发式搜索 A*算法 历史: 1964年Nils ...
- 启发式搜索A-Star算法 【寻找 最短路径 算法】【地理几何位置 可利用的情况】
在处理最短路径问题时,有一种启发式算法是我们应该了解的,由于其有着优秀的探索效率在各自现实项目中多有应用,它就是 A-star 算法,或 A* 算法. 个人观点: A* 算法并不保证找到的路径一 ...
- 启发式搜索 A*算法的OC 实现
前两天重新学习了下A*算法,上次学习A*算法已经是5年前了,看到网上铺天盖地的A*算法都是C.C++等等其他语言的,就是没有OC 的,所以抽空写了一份.今天太晚了就不说明A*算法的细节了,大家如果想学 ...
- A*搜寻算法(A星算法)
A*搜寻算法[编辑] 维基百科,自由的百科全书 本条目需要补充更多来源.(2015年6月30日) 请协助添加多方面可靠来源以改善这篇条目,无法查证的内容可能会被提出异议而移除. A*搜索算法,俗称A星 ...
- 【算法入门】深度优先搜索(DFS)
深度优先搜索(DFS) [算法入门] 1.前言深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍历的算法.它的思想是从一个顶点V0开始,沿着一条路一直走到底,如果发现不能到达目标解 ...
- 深度优先搜索(DFS)
[算法入门] 郭志伟@SYSU:raphealguo(at)qq.com 2012/05/12 1.前言 深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍历的算法.它的思想是从一 ...
- POJ 2449 Remmarguts' Date --K短路
题意就是要求第K短的路的长度(S->T). 对于K短路,朴素想法是bfs,使用优先队列从源点s进行bfs,当第K次遍历到T的时候,就是K短路的长度. 但是这种方法效率太低,会扩展出很多状态,所以 ...
- dfs介绍
深度优先搜索(DFS) [算法入门] 郭志伟@SYSU:raphealguo(at)qq.com 2012/05/12 1.前言 深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍 ...
随机推荐
- php中比较好用的函数
PHP中一个好用的函数parse_url,特别方便用来做信息抓取的分析,举例子如下: $url = "http://www.electrictoolbox.com/php-extract-d ...
- poj 1298 The Hardest Problem Ever
题目链接:http://poj.org/problem?id=1298 题目大意:按照所给的顺序要求将输入的字符串进行排列. #include <iostream> #include &l ...
- ubuntu安装wifi
因为需要测试app,但是自己本地是deepin.如果win下的话直接安装一个wifi万能管家啥的就完事儿了.可是这个是linux 有点不同.所以就进行百度学习了一波.特此分享. 需要用到的工具 hos ...
- 64_k1
KoboDeluxe-0.5.1-22.fc26.x86_64.rpm 13-Feb-2017 22:11 1626454 k3b-17.04.1-1.fc26.x86_64.rpm 25-May-2 ...
- Shell脚本中引用、调用另一个脚本文件的2种方法
Shell脚本中引用.调用另一个脚本文件的2种方法 http://www.jb51.net/article/67903.htm
- openfire在内网的情况下 文件传输代理的设置
openfire在内网的情况下 文件传输代理的设置 http://blog.csdn.net/v6543210/article/details/22506565
- C# 判断一个单链表是否有环及环长和环的入口点
1.为什么写这个随笔? 前几天参加一个电面,被问到这个问题,想总结一下. 2.为什么标题强调C#? 想在网上看看代码,却没找到C#版的,于是自己用C#实现一下. 一.解决问题的思路 1.一种比较耗空间 ...
- 图论-强连通分量-Tarjan算法
有关概念: 如果图中两个结点可以相互通达,则称两个结点强连通. 如果有向图G的每两个结点都强连通,称G是一个强连通图. 有向图的极大强连通子图(没有被其他强连通子图包含),称为强连通分量.(这个定义在 ...
- python库-urllib
urllib库提供了一系列操作url的功能,是python处理爬虫的入门级工具,网上的学习资料也很多.我做爬虫是一开始就用了Scrapy框架,并不是一步步从urllib开始的,反而是在后来解决一些小问 ...
- Nginx web proxy NFS服务
1.nginx web 安装 配置 #systemctl stop firewalld #systemctl disabled firewalld #wget -O /etc/yum.repos.d/ ...