hdu-1043(八数码+bfs打表+康托展开)
参考文章:https://www.cnblogs.com/Inkblots/p/4846948.html
康托展开:https://blog.csdn.net/wbin233/article/details/72998375
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043
题意:给出一串数(有9个,其中有一个x),表示这些数再3*3的矩阵中的排序序列,如果可以通过交换x与其他数字的操作,
最终得到目的矩阵(eg:12345678x),就输出x的移动方向。分别用u表示向上,d表示向下,l向左,r向右。
思路:考察八数码的知识,由于数据总量可以接受,可以用bfs打表的方式先列出存在的每个情况,利用康托展开的映射关系(也就是每一个序列对应一个hash值)
来求出移动的方向。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std; #define MAX 400000
#define AIM 46234 //124567890对应的hash值 bool v[MAX];
char path[MAX][]; //总路径
int len; char dir[]="durl"; //反向搜索
int mov[][]={{-,},{,},{,-},{,}}; //八数码状态结构体
struct Node{
int s[];
int loc;
int status; //hash值排列值
int fa; //记录父状态
char d; //移动方向
};
Node n[MAX]; int fac[]={,,,,,,,,,}; //康托展开对应的hash值 int Inverse_cantor(int s[])
{
int sum=;
for(int i=;i<;i++)
{
int num=;
for(int j=i+;j<;j++) //逆序数计数器 (康托展开需要)
{
if(s[j]<s[i]) num++;
}
sum+=num*fac[-i-];
}
return sum+;
} void count_path(Node end) //反向记录路径
{
int status = end.status;
int f=end.fa;
len=;
path[status][len++]=end.d;
while(f)
{
path[status][len++]=n[f].d; //记录方向
f=n[f].fa; //查找父状态方向
}
} void BFS()
{
memset(v,,sizeof(v));
Node next;
int head=,tail=;
for(int i=;i<;i++) //目标状态
n[].s[i]=i+; n[].s[]=;
n[].loc=;//空位是8
n[].status=AIM;
v[AIM]=true;
while(head<=tail)
{
int x=n[head].loc/;
int y=n[head].loc%;
for(int i=;i<;i++) //遍历四个方向
{
int tx=x+mov[i][];
int ty=y+mov[i][];
if(tx<||tx>||ty<||ty>) continue; next=n[head]; //更新状态
next.loc=tx*+ty; //计算新空位
next.s[n[head].loc]=next.s[next.loc]; //原空位替换
next.s[next.loc]=; //新空位
next.fa=head;
next.d=dir[i];
next.status=Inverse_cantor(next.s);
//判断重复,并且新入队列
if(!v[next.status])
{
v[next.status]=true;
count_path(next);
n[++tail]=next;
}
}
head++;
}
} int main(void)
{
BFS();
char ch[];
Node cur;
while(~scanf("%s",ch))
{
if(!strcmp(ch,"x")) cur.s[]=,cur.loc=;
else cur.s[]=ch[]-'';
for(int i=;i<;i++)
{
scanf("%s",ch);
if(!strcmp(ch,"x"))
cur.s[i]=,cur.loc=i;
else cur.s[i]=ch[]-'';
}
cur.status=Inverse_cantor(cur.s);
if(v[cur.status])
printf("%s\n",path[cur.status]);
else printf("unsolvable\n");
}
return ;
}
hdu-1043(八数码+bfs打表+康托展开)的更多相关文章
- HDU 1043 Eight(反向BFS+打表+康托展开)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 题目大意:传统八数码问题 解题思路:就是从“12345678x”这个终点状态开始反向BFS,将各 ...
- Eight POJ - 1077 HDU - 1043 八数码
Eight POJ - 1077 HDU - 1043 八数码问题.用hash(康托展开)判重 bfs(TLE) #include<cstdio> #include<iostream ...
- HDU1043 Eight(八数码:逆向BFS打表+康托展开)题解
Eight Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Sub ...
- HDU1043 八数码(BFS + 打表)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 , 康托展开 + BFS + 打表. 经典八数码问题,传说此题不做人生不完整,关于八数码的八境界 ...
- HDU 1043 八数码(八境界)
看了这篇博客的讲解,挺不错的.http://www.cnblogs.com/goodness/archive/2010/05/04/1727141.html 判断无解的情况(写完七种境界才发现有直接判 ...
- HDU 1043 八数码(A*搜索)
在学习八数码A*搜索问题的时候须要知道下面几个点: Hash:利用康托展开进行hash 康托展开主要就是依据一个序列求这个序列是第几大的序列. A*搜索:这里的启示函数就用两点之间的曼哈顿距离进行计算 ...
- HDU 1043 八数码问题的多种解法
一.思路很简单,搜索.对于每一种状态,利用康托展开编码成一个整数.于是,状态就可以记忆了. 二.在搜索之前,可以先做个优化,对于逆序数为奇数的序列,一定无解. 三.搜索方法有很多. 1.最普通的:深搜 ...
- hdu 1043 八数码问题
Eight Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- HDU 1043 八数码 Eight A*算法
Eight Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
随机推荐
- SQL Server中row_number的用法
ROW_NUMBER()函数将针对SELECT语句返回的每一行,从1开始编号,赋予其连续的编号.在查询时应用了一个排序标准后,只有通过编号才能够保证其顺序是一致的,当使用ROW_NUMBER函数时,也 ...
- FortiGate基本信息
1.介绍 FortiGate是全新的下一代防火墙,在整个硬件架构和系统上面都有新的设计,在性能和功能上面都有了很大提升,具有性能高.接口丰富.功能齐全.安全路由交换一体化.性价比高等优势. Forti ...
- Inno Setup界面拉伸
1.源起: 源于一个安装包的广告定制.广告客服提供的图片太大,inno setup默认尺寸容不下它,需要扩充,拉宽安装界面尺寸. 以inno setup所附带例子说事,其默认尺寸如下: 2.Scale ...
- linux命令学习之:tar
tar命令可以为linux的文件和目录创建档案.利用tar,可以为某一特定文件创建档案(备份文件),也可以在档案中改变文件,或者向档案中加入新的文件.tar最初被用来在磁带上创建档案,现在,用户可以在 ...
- go语言中的反射reflect
package main; import ( "fmt" "reflect" ) //反射refection //反射使用TypeOf和ValueOf函数从接口 ...
- 一、MySQL的连接建立与权限
一.MySQL的连接建立与权限 写这些的目的一是记录下工作这几年所学,算是成长脚印吧.二是复习一遍,也给自己当笔记看,通篇观点都属于个人理解较多.读者观看的时候也需要自己判断下是否正确,另外,记下一段 ...
- vue slot插槽的使用方法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- c# ?. 空值传播运算符
当左侧为空时不执行右侧代码,避免出现为null的错误,同时也避免了判断是否为null,可以和??一起连用,省了好多事.举例如下: 以前:var res=obj==null?5:obj.a; 现在:va ...
- Django——模板语言相关内容
Django模板语言相关内容 Django模板系统 官方文档 常用语法 只需要记两种特殊符号: {{ }}和 {% %} 变量相关的用{{}},逻辑相关的用{%%}. 变量 {{ 变量名 }} ...
- 关于document的节点;用Dom2创建节点;
一.关于节点 1.节点树状图 document>documentElement>body>tagName 2.节点类型 元素节点(标签).文本节点(文本).属性节点(标签属性) 3. ...