一个舰队的目标状态如上图。红色是旗舰。然后给你初始局面,每一次决策可以把旗舰和其上一层或下一层的两个相邻的进行交换。如果能在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的更多相关文章

  1. 启发式搜索A*算法

    A* 寻路算法 (2011-02-15 10:53:11) 转载▼ 标签: 游戏 分类: 算法 概述 虽然掌握了 A* 算法的人认为它容易,但是对于初学者来说, A* 算法还是很复杂的. 搜索区域(T ...

  2. 启发式搜索——A*算法

    启发式搜索 启发式搜索是一种对搜索到的每一个位置进行评估,然后从评估的最优位置进行搜索直到目的地, 由于搜索时对每一个位置的评估是基于直观或经验的所有叫启发式搜索 A*算法 历史: 1964年Nils ...

  3. 启发式搜索A-Star算法 【寻找 最短路径 算法】【地理几何位置 可利用的情况】

    在处理最短路径问题时,有一种启发式算法是我们应该了解的,由于其有着优秀的探索效率在各自现实项目中多有应用,它就是 A-star 算法,或  A*  算法. 个人观点: A*  算法并不保证找到的路径一 ...

  4. 启发式搜索 A*算法的OC 实现

    前两天重新学习了下A*算法,上次学习A*算法已经是5年前了,看到网上铺天盖地的A*算法都是C.C++等等其他语言的,就是没有OC 的,所以抽空写了一份.今天太晚了就不说明A*算法的细节了,大家如果想学 ...

  5. A*搜寻算法(A星算法)

    A*搜寻算法[编辑] 维基百科,自由的百科全书 本条目需要补充更多来源.(2015年6月30日) 请协助添加多方面可靠来源以改善这篇条目,无法查证的内容可能会被提出异议而移除. A*搜索算法,俗称A星 ...

  6. 【算法入门】深度优先搜索(DFS)

    深度优先搜索(DFS) [算法入门] 1.前言深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍历的算法.它的思想是从一个顶点V0开始,沿着一条路一直走到底,如果发现不能到达目标解 ...

  7. 深度优先搜索(DFS)

    [算法入门] 郭志伟@SYSU:raphealguo(at)qq.com 2012/05/12 1.前言 深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍历的算法.它的思想是从一 ...

  8. POJ 2449 Remmarguts' Date --K短路

    题意就是要求第K短的路的长度(S->T). 对于K短路,朴素想法是bfs,使用优先队列从源点s进行bfs,当第K次遍历到T的时候,就是K短路的长度. 但是这种方法效率太低,会扩展出很多状态,所以 ...

  9. dfs介绍

    深度优先搜索(DFS) [算法入门] 郭志伟@SYSU:raphealguo(at)qq.com 2012/05/12 1.前言 深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍 ...

随机推荐

  1. python数据处理课程笔记(一)

    一.numpy 1.numpy中所有元素必须是相同的类型 a=[1,2,3,4,'t'] #列表中有str类型,转换为ndarray时所有元素都转换为str类型 arr1=np.array(a) pr ...

  2. bzoj 1588 bst

    用set存下就好了. /************************************************************** Problem: 1588 User: BLADE ...

  3. 第一章:获取服务器服务banner

    #!c:\\perl\\bin\\perl.exe #读取服务器的首行(banner) use IO::Socket; my $service = '121.201.67.177:ssh'; my $ ...

  4. python 异步IO( asyncio) 协程

    python asyncio 网络模型有很多中,为了实现高并发也有很多方案,多线程,多进程.无论多线程和多进程,IO的调度更多取决于系统,而协程的方式,调度来自用户,用户可以在函数中yield一个状态 ...

  5. AJAX 核心 —— XMLHTTPRequest 对象回顾

    一.AJAX概述 不使用 AJAX 的网页,如果要更新内容,需要重载整个页面. AJAX ( Asynchronous Javascript And XML ,异步 Javascript 和 XML) ...

  6. Laravel 5.2 整合 Uploadify 上传图片

    前端: <!-- 引入CSS.JS --> <link rel="stylesheet" type="text/css" href=" ...

  7. selenium遇到的一些问题,持续更新

    1.今天早上运行程序的时候,发现我在循环点击一个元素的时候出现了错误 selenium.common.exceptions.StaleElementReferenceException: Messag ...

  8. 【ZJOI2016】大森林

    这题理论上可以用ETT,但是用LCT建虚点可以解决这个问题. 对于最晚的操作1建立一个虚点,然后把操作0挂上去. #include<bits/stdc++.h> ; using names ...

  9. 【数位dp入门】【HDU4734】F(x)

    记录减的状态,表示还要凑多少才能达到当前值. 然后进行枚举即可.注意状态数不能重复. #include<bits/stdc++.h> #define N 10010 using names ...

  10. VPS性能测试(2):内存大小、交换空间、高速缓存、实际使用内存

    1.要想查看购买的VPS主机的内存信息,执行:cat /proc/meminfo,主要是看内存大小.交换空间.高速缓存 2.VPS主机实际使用内存大小.Linux管理内存的机制是这样的:无论物理内存有 ...