hdu 1043 Eight(双向bfs)
题意:经典八数码问题
思路:双向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)的更多相关文章
- 2017多校第10场 HDU 6171 Admiral 双向BFS或者A*搜索
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6171 题意: 给你一个高度为6的塔形数组,你每次只能将0与他上下相邻的某个数交换,问最少交换多少次可以 ...
- HDU 1242 -Rescue (双向BFS)&&( BFS+优先队列)
题目链接:Rescue 进度落下的太多了,哎╮(╯▽╰)╭,渣渣我总是埋怨进度比别人慢...为什么不试着改变一下捏.... 開始以为是水题,想敲一下练手的,后来发现并非一个简单的搜索题,BFS做肯定出 ...
- HDU 3085 Nightmare Ⅱ (双向BFS)
Nightmare Ⅱ Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- HDU 3085 Nightmare Ⅱ 双向BFS
题意:很好理解,然后注意几点,男的可以一秒走三步,也就是三步以内的都可以,鬼可以穿墙,但是人不可以,鬼是一次走两步 分析:我刚开始男女,鬼BFS三遍,然后最后处理答案,严重超时,然后上网看题解,发现是 ...
- HDU 1043 Eight(反向BFS+打表+康托展开)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 题目大意:传统八数码问题 解题思路:就是从“12345678x”这个终点状态开始反向BFS,将各 ...
- Nightmare Ⅱ HDU - 3085 (双向bfs)
Last night, little erriyue had a horrible nightmare. He dreamed that he and his girl friend were tra ...
- ACM-BFS之Open the Lock——hdu1195(双向BFS)
这道题的0基础版本号,暴力BFS及题目详情请戳:http://blog.csdn.net/lttree/article/details/24658031 上回书说道,要用双向BFS来尝试一下. 最终A ...
- HDU 1043 Eight(双向BFS+康托展开)
http://acm.hdu.edu.cn/showproblem.php?pid=1043 题意:给出一个八数码,求出到达指定状态的路径. 思路:路径寻找问题.在这道题里用到的知识点挺多的.第一次用 ...
- 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 ...
随机推荐
- set_include_path() &&get_include_path()用法
function initialize(){ set_include_path(get_include_path().PATH_SEPARATOR . "core/"); ...
- (11)UML设计视图
UML的词汇表包含三种构造块:事物.关系和图 事物:事物是对模型中最具有代表性的成分的抽象 关系:把事物结合在一起 图:图聚集了相关的事物 一.事物 UML中有4种事物 (1)结构事物 UML 模型中 ...
- js -- 侧边悬浮栏特效
github: https://github.com/mybee/float-scroll-page #menu{width: 120px;height: auto; position: fixed; ...
- Mysql 性能优化20个原则(2)
5. 在Join表的时候使用相当类型的例,并将其索引 如果你的应用程序有很多 JOIN 查询,你应该确认两个表中Join的字段是被建过索引的.这样,MySQL内部会启动为你优化Join的SQL语句的机 ...
- 配置 yum 源相关
1. 修改yum配置 http://www.cnblogs.com/shuaixf/archive/2011/11/30/2268496.html 2. centos安装 epel 源 https:/ ...
- [Javascript] Use a custom sort function on an Array in Javascript
Sorting in Javascript with sort uses lexical sorting by default, which means it will sort in alphabe ...
- Intel Edision —— 从SSH无法连接到systemd
前言 原创文章,转载引用务必注明链接.如有疏漏,欢迎斧正. 最近在试用Wyliodrin,安装过程中出现了两个问题,一是无法使用SSH登录到Edison:二是EDISON磁盘的问题.分别涉及到syst ...
- ZOJ ACM 1314(JAVA)
昨天做了几个题目.过于简单,就不在博客里面写了. 1314这道题也比較简单,写出来是由于我认为在这里有一个小技巧,对于时间复杂度和空间复杂度都比較节省. 这个题目类似哈希表的求解.可是更简单.刚拿到题 ...
- C#语法复习1
一.C#与.net框架 .net是语言无关的. 程序的执行流程: .net兼容语言的源代码文件 .net兼容编译器 程序集(公共中间语言(CIL)common intermediate languag ...
- MYSQL时间戳的处理
date为需要处理的参数(该参数是Unix 时间戳),可以是字段名,也可以直接是Unix 时间戳字符串 后面的 '%Y%m%d' 主要是将返回值格式化 例如: mysql>SELECT FROM ...