题目描述

在一个 3×3 的网格中,1∼8 这 8个数字和一个 X 恰好不重不漏地分布在这 3×3 的网格中。

例如:

1 2 3
X 4 6
7 5 8

在游戏过程中,可以把 X 与其上、下、左、右四个方向之一的数字交换(如果存在)。

我们的目的是通过交换,使得网格变为如下排列(称为正确排列):

1 2 3
4 5 6
7 8 X

例如,示例中图形就可以通过让 X 先后与右、下、右三个方向的数字交换成功得到正确排列。

交换过程如下:

1 2 3   1 2 3   1 2 3   1 2 3
X 4 6   4 X 6   4 5 6   4 5 6
7 5 8   7 5 8   7 X 8   7 8 X

把 X 与上下左右方向数字交换的行动记录为 udlr

现在,给你一个初始网格,请你通过最少的移动次数,得到正确排列。

输入格式

输入占一行,将 3×33×3 的初始网格描绘出来。

例如,如果初始网格如下所示:

1 2 3
x 4 6
7 5 8

则输入为:1 2 3 x 4 6 7 5 8

输出格式

输出占一行,包含一个字符串,表示得到正确排列的完整行动记录。

如果答案不唯一,输出任意一种合法方案即可。

如果不存在解决方案,则输出 unsolvable

输入样例:

2  3  4  1  5  x  7  6  8

输出样例

ullddrurdllurdruldr

思路

首先,八数码有解判断的必要条件:逆序对的个数若为偶数个时有解,若为奇数个则无解。详见图(借,有问题则删,https://www.acwing.com/solution/content/35528/)

其次,对于使用astar优化时,因为当我们移动一个点的时候,只能上下左右间移动,因此 f(n) 预估距离的设定,这里定义为当前图各个点到最终图各个点的哈夫曼距离之和。

参考代码:

#include <bits/stdc++.h>#define io ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)#define LL long long#define x first#define y second#define PII pair<int,int>#define PIS pair<int,string>#define PIII pair<int,PII>#define PDD pair<double,double>using namespace std;const int INF=0x3f3f3f3f;const int N=1005;const int M=1e7;const int mod=1e9+7;/*八数码有解判断的必要条件:逆序对的个数若为偶数个时有解,若为奇数个则无解。*///当前点到终点的预估距离,每个位置点距离自己正确位置的哈夫曼距离和// abs(xs-xe)+abs(ys-ye);int f(string state){int res = 0;int len=state.length();for(int i=0;i<len;i++){if(state[i] != 'x'){int t = state[i] - '1';res += abs(i/3 - t/3)+abs(i%3 - t%3);}}return res;}string start; //存初始状态int dir[4][2]={-1,0,1,0,0,-1,0,1};char go[]="udlr";string astar(){//最终状态string end="12345678x";map<string , int> dis; //到这个状态的实际距离map<string , pair<string,char> >pre; //到这个状态的,前个状态和动作priority_queue<PIS,vector<PIS>,greater<PIS> >q;q.push({f(start),start});dis[start]=0;while(q.size()){auto tmp=q.top();q.pop();//当前状态string state=tmp.y;//到达最终状态,退出if(state==end)break;//获取当前步数int step=dis[state];int x,y;//找到操作"X"的位置for(int i=0;i<9;i++){if(state[i]=='x'){x=i/3;y=i%3;break;}}//存储当前状态string source=state;//开始向4个方向扩展for(int i=0,nx,ny;i<4;i++){nx=x+dir[i][0];ny=y+dir[i][1];if(nx<0 || nx>=3 || ny<0 || ny>=3)continue;//交换2点位置swap(state[x*3+y],state[nx*3+ny]);/*更新状态的2种情况:1.若移动后的状态不存在2.若移动后的状态所用步数大于当前状态,则表示移动后的状态下都可以被更新*/if(dis.count(state)==0 || dis[state]>step+1){//更新实际距离dis[state]=step+1;//记录前驱,{前一个状态,动作}pre[state]={source,go[i]};q.push({dis[state]+f(state),state});}//回溯2点位置swap(state[x*3+y],state[nx*3+ny]);}}//反向遍历操作结果string res="";while(end!=start){res+=pre[end].y;end=pre[end].x;}reverse(res.begin(),res.end());return res;}int main(){char c;string str; //用来判断逆序对for(int i=0;i<9;i++){cin>>c;if(c!='x')str+=c;start+=c;}int cnt=0; //逆序对个数for(int i=0;i<str.length();i++){for(int j=i+1;j<str.length();j++){if(str[i]>str[j])cnt++;}}//奇数个,无解if(cnt&1)cout<<"unsolvable\n";//偶数个,存在解else cout<<astar()<<"\n";system("pause");return 0;}

八数码 (Astar)相关推荐

  1. AcWing 179. 八数码 178. 第K短路 (A-star)

    A-star 算法 算法证明略 做题步骤: 如果搜索空间过大,考虑使用A*算法,正常做真实距离,思考估价函数,验证估价函数的正确性,队列换成优先队列,新加一维 真实+估计,终点出队即为答案 AcWin ...

  2. 基于Python实现的AStar求解八数码问题

    资源下载地址:https://download.csdn.net/download/sheziqiong/86776612 资源下载地址:https://download.csdn.net/downl ...

  3. Astar、A星算法解决八数码问题--python实现

    一.问题描述 数码问题又称9宫问题,与游戏"华容道"类似.意在给定的3*3棋格的8个格子内分别放一个符号,符号之间互不相同,余下的一格为空格.并且通常把8个符号在棋格上的排列顺序称 ...

  4. HUD 1043 Eight 八数码问题 A*算法 1667 The Rotation Game IDA*算法

    先是这周是搜索的题,网站:http://acm.hdu.edu.cn/webcontest/contest_show.php?cid=6041 主要内容是BFS,A*,IDA*,还有一道K短路的,.. ...

  5. 《人工智能》实验二——搜索技术(八数码问题)

    必须记住下一步还可以走哪些点--OPEN表(记录还没有扩展的点) 必须记住哪些点走过了--CLOSED表(记录已经扩展的点 广度优先搜索 在应用BFS算法进行八数码问题搜索时需要open和closed ...

  6. Nilsson's sequence score算法解决八数码问题解释

    解决了最近一个人工智能关于解决八数码难题的作业. 图可能看不清,除了黑块外其他位置是英文字母ABCDEFGH A*:f(n)=g(n)+h(n) 其中f为总花费,g为已知花费(深度),h为估计花费 关 ...

  7. 学习笔记--八数码问题

    题目链接 https://www.luogu.org/problemnew/show/P1379 分析 经典的八数码问题,有双向BFS和\(IDA*\)的方法,这里使用的是\(A*\)启发式搜索. 简 ...

  8. 使用Muduo完成数独和八数码问题求解服务器

    在剖析完Muduo网络库源码之后,我们试着完成一个高效的数独和八数码问题求解服务器. 先说说为什么要选择这两个问题?数独问题一直是陈硕老师很喜欢的问题,在muduo网络库中多次提到并有示例.八数码问题 ...

  9. 习题:八数码难题(双向BFS)

    八数码难题(wikioi1225) [题目描述] 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出 ...

  10. AI 八数码A_star算法问题-实验报告

    一 题目要求: 八数码问题的A星搜索算法实现         要求:设计估价函数,并采用c或python编程实现,以八数码为例演示A星算法的搜索过程,争取做到直观.清晰地演示算法,代码要适当加注释. ...

最新文章

  1. HarmonyOS Text设置换行
  2. android数据库降级_android——数据库版本升/降级问题
  3. Lucene 4.X 倒排索引原理与实现: (3) Term Dictionary和Index文件 (FST详细解析)——直接看例子就明白了!!!...
  4. 【BZOJ4405】【WC2016】挑战NPC(带花树)
  5. python实现WebsocketServer 服务端
  6. 发现一个骨灰级图形学大神的博客
  7. CDOJ 1269 ZhangYu Speech
  8. 普通人改变命运最关键的这几种方法
  9. python子类分配
  10. Python-pillow库显示MNIST图片的方法
  11. 面向连接服务与无连接服务
  12. 每日一题(44)—— 请列举一个软件中时间换空间或者空间换时间的例子
  13. excel 某个单元格不是等于空值,Excel返回第一个与所有非空单元格及统计数量,把空单元格替换为0...
  14. U3D_Shader编程(第一篇:快速入门篇)
  15. Java反射 二三事
  16. [励志][经验]《异类》 -- 格拉德威尔(美)
  17. 计算机中的一些基本概念(速度,比特,门,电路图)
  18. 本文主要讲述如何开通自己的博客。若读者不想或已经知道如何开通使用博客,那么就可以跳过。 一直以来,想把自己在学习过程中遇到的问题及解决办法共享给志同道合的人,那么如何分享自己的见解呢?有如下方法
  19. 邮件狂人告诉你:如何打造最强邮件处理流
  20. 手把手教你使用ModelArts的自动学习识别毒蘑菇分类

热门文章

  1. 用python制作微信小程序_微信小程序能用python开发
  2. ce修改手游服务器的数据,CE修改器修改游戏数据的方法
  3. 怎么制定合理的开发计划
  4. Unity移动的三种方式
  5. 社交网络分析算法(SNA)
  6. C#实现海康人脸门禁主机远程开关门和下发用户数据
  7. Python:实现random forest regressor随机森林回归器算法(附完整源码)
  8. 软件测试理论、方法及流程
  9. [概率统计]商务与经济统计知识点总结 Part 2
  10. IDEA 运行 Tomcat 中文乱码的各种问题