题意:经典八数码问题

思路:双向bfs

ps:还有a*算法(还不会)等解法。

代码:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std; #define MAXN 362885//最多组合个数:9!=362880 int dir[]={-,,-,};//4个方向移动:u,d,l,r
char opF[]={'u','d','l','r'};//正向bfs操作
char opR[]={'d','u','r','l'};//反向bfs操作
int fac[]={,,,,,,,,};//阶乘
bool visF[MAXN];//正向访问标志
bool visR[MAXN];//
string sTarg="";//目标棋盘 struct node{//存储棋盘信息
string s;//当前棋盘
int xLoca;//x位置
}t; struct node2{//存储操作
int idF,idR;//正向前驱、反向前驱
char cF,cR;//操作
}op[MAXN]; int cantor_hash(string s){//康托展开,一共n位
int n=;//共9位
int i,j,temp,num;
num=;
for(i=;i<n-;i++){//n为位数
temp=;
for(j=i+;j<n;j++){
if(s[j]<s[i])temp++;
}
num+=fac[n-(i+)]*temp;
}
return num;//从0开始
} void display(int i){//输出正向操作
if(op[i].idF==-)return;
display(op[i].idF);
printf("%c",op[i].cF);
} void dBfs(){
queue<node>qF,qR;//正向队列,反向队列
node tmp1,tmp2;//棋盘状态临时变量
int id_hash,id_hash2,xLoca,i;//id 康托哈希下标值,xLoca 暂存x位置 tmp1=t;//初始状态 tmp2.s=sTarg;//目标状态
tmp2.xLoca=;//目标状态x位置 id_hash=cantor_hash(tmp1.s);//初始状态
visF[id_hash]=true;
op[id_hash].idF=-;
qF.push(tmp1); id_hash=cantor_hash(tmp2.s);//目标状态
visR[id_hash]=true;
op[id_hash].idR=-;
qR.push(tmp2); while(!qF.empty()&&!qR.empty()){
//正向bfs
tmp1=qF.front();
qF.pop();
id_hash=cantor_hash(tmp1.s);
if(visR[id_hash]){//反向bfs也访问过
display(id_hash);
id_hash2=id_hash;
while(op[id_hash2].idR!=-){
printf("%c",op[id_hash2].cR);
id_hash2=op[id_hash2].idR;
}
printf("\n");
return;
}
for(i=;i<;++i){
if(i==&&tmp1.xLoca<)continue;
if(i==&&tmp1.xLoca>)continue;
if(i==&&tmp1.xLoca%==)continue;
if(i==&&tmp1.xLoca%==)continue;
xLoca=tmp1.xLoca+dir[i]; tmp2=tmp1;
swap(tmp2.s[tmp1.xLoca],tmp2.s[xLoca]);
id_hash2=cantor_hash(tmp2.s);
if(!visF[id_hash2]){
visF[id_hash2]=true;
tmp2.xLoca=xLoca;
op[id_hash2].idF=id_hash;
op[id_hash2].cF=opF[i];
qF.push(tmp2);
}
} //反向bfs
tmp1=qR.front();
qR.pop();
id_hash=cantor_hash(tmp1.s);
if(visF[id_hash]){//正向bfs也访问过
display(id_hash);
id_hash2=id_hash;
while(op[id_hash2].idR!=-){
printf("%c",op[id_hash2].cR);
id_hash2=op[id_hash2].idR;
}
printf("\n");
return;
}
for(i=;i<;++i){
if(i==&&tmp1.xLoca<)continue;
if(i==&&tmp1.xLoca>)continue;
if(i==&&tmp1.xLoca%==)continue;
if(i==&&tmp1.xLoca%==)continue;
xLoca=tmp1.xLoca+dir[i]; tmp2=tmp1;
swap(tmp2.s[tmp1.xLoca],tmp2.s[xLoca]);
id_hash2=cantor_hash(tmp2.s);
if(!visR[id_hash2]){
visR[id_hash2]=true;
tmp2.xLoca=xLoca;
op[id_hash2].idR=id_hash;
op[id_hash2].cR=opR[i];
qR.push(tmp2);
}
}
}
} int main(){
char str[];//串
int len;//串长度
int i,j,k;//k 第几个数码
int ivsNum;//逆序数
while(~scanf("%[^\n]",str)){
getchar();//吸收回车 memset(visF,false,sizeof(visF));
memset(visR,false,sizeof(visR)); len=strlen(str);
t.s="";
k=;//第几个数码
for(i=;i<len;++i){//处理字符串
if(str[i]!=' '){
if(str[i]=='x'){
t.s=t.s+'';
t.xLoca=k;
}
else t.s=t.s+str[i];
++k;//
}
} ivsNum=;//逆序数初始为0
for(i=;i<;++i){
if(t.s[i]=='')continue;
for(j=;j<i;++j){
if(t.s[j]=='')continue;
if(t.s[j]>t.s[i])++ivsNum;
}
}
if(ivsNum&)printf("unsolvable\n");//逆序数为奇数
else dBfs();//双向bfs
}
return ;
}

hdu 1043 Eight(双向bfs)的更多相关文章

  1. 2017多校第10场 HDU 6171 Admiral 双向BFS或者A*搜索

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6171 题意: 给你一个高度为6的塔形数组,你每次只能将0与他上下相邻的某个数交换,问最少交换多少次可以 ...

  2. HDU 1242 -Rescue (双向BFS)&amp;&amp;( BFS+优先队列)

    题目链接:Rescue 进度落下的太多了,哎╮(╯▽╰)╭,渣渣我总是埋怨进度比别人慢...为什么不试着改变一下捏.... 開始以为是水题,想敲一下练手的,后来发现并非一个简单的搜索题,BFS做肯定出 ...

  3. HDU 3085 Nightmare Ⅱ (双向BFS)

    Nightmare Ⅱ Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  4. HDU 3085 Nightmare Ⅱ 双向BFS

    题意:很好理解,然后注意几点,男的可以一秒走三步,也就是三步以内的都可以,鬼可以穿墙,但是人不可以,鬼是一次走两步 分析:我刚开始男女,鬼BFS三遍,然后最后处理答案,严重超时,然后上网看题解,发现是 ...

  5. HDU 1043 Eight(反向BFS+打表+康托展开)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 题目大意:传统八数码问题 解题思路:就是从“12345678x”这个终点状态开始反向BFS,将各 ...

  6. Nightmare Ⅱ HDU - 3085 (双向bfs)

    Last night, little erriyue had a horrible nightmare. He dreamed that he and his girl friend were tra ...

  7. ACM-BFS之Open the Lock——hdu1195(双向BFS)

    这道题的0基础版本号,暴力BFS及题目详情请戳:http://blog.csdn.net/lttree/article/details/24658031 上回书说道,要用双向BFS来尝试一下. 最终A ...

  8. HDU 1043 Eight(双向BFS+康托展开)

    http://acm.hdu.edu.cn/showproblem.php?pid=1043 题意:给出一个八数码,求出到达指定状态的路径. 思路:路径寻找问题.在这道题里用到的知识点挺多的.第一次用 ...

  9. Eight (HDU - 1043|POJ - 1077)(A* | 双向bfs+康拓展开)

    The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've see ...

随机推荐

  1. idea 自定义工具栏

    问题:在笔记本上面使用idea的时候,有时候,需要使用 Ctrl+Alt+左箭头 /  Ctrl+Alt+右箭头 跳转到 上一次,查看代码的问题,然而存在快捷冲突的时候,很蛋疼.下面是解决办法. 效果 ...

  2. unity的List构造函数在IOS平台存在缺陷

    当迩使用一个int[]或者string[]类似的数组时,以数组来初始化List对象,有可能在IOS平台上会出现初始化对象为空,比如 , }; List<int> listTest = ne ...

  3. ActivityGroup中监听返回按键

    如果你想使用ActivityGroup来统一管理Activity的话,当然首先这是一种很好的方法,但是如果你想在ActivityGroup里面拦截返回按键来进行统一管理的话,直接覆写onKeyDown ...

  4. webstorm(三):webstorm的一些waring提示

    一.Attribute key is not allowed here 二.Comparison this.loginType != 'username' may cause unexpected t ...

  5. Docker 的CMD与ENTRYPOINT区别

    我们在构建一个docker镜像的时候,Dockerfile里面有两个命令会引起我们的注意,它们就是 CMD 和 ENTRYPOINT,看起来很相似,实际上并非如此. 一.CMD 顾名思义就是允许用户指 ...

  6. Mac--安装kubernetes并运行echoserver

    安装minikube curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.15.0/minikube-darwi ...

  7. centos 7 -- Disk Requirements: At least 134MB more space needed on the / filesystem.

    用了幾年的centos7,今天執行yum update時,彈出一行有錯誤的提示:Disk Requirements:   At least 134MB more space needed on the ...

  8. memcached优化方法

    工作原理     基本概念:slab,page.chunk.     slab,是一个逻辑概念. 它是在启动memcached实例的时候预处理好的,每一个slab相应一个chunk size.也就是说 ...

  9. 在运行hadoop是出现Master的9000端口拒绝访问的情况

    出现9000端口拒绝访问的情况有可能是防火墙没有开放9000端口,可以选择关闭防火墙或者卸载防火墙,如果还是无法解决这种情况可能是因为hadoop的启动顺序不对. 应该按照如下得顺序启动 Step2: ...

  10. Vue 基础

    1. data 数据 methods 方法 watch 监听变化 2. 模版指令(类似 angular) {{}} v-text 渲染数据 v-html html 结构 3. v-if v-show ...