题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 , 康托展开 + BFS + 打表。

  经典八数码问题,传说此题不做人生不完整,关于八数码的八境界:http://www.cnblogs.com/goodness/archive/2010/05/04/1727141.html

  我自己是用哈希(康托展开) + BFS  + 打表过的,第三重境界。

  由于一些高级的搜索现在还没学,所以目前能升级的也就是用双向BFS来做了,等过几天有心情了来做。

  本文长期更新。


算法:  

  由于此题是求某个起始状态到“12345678X”的步骤,所以可以考虑先求出“12345678X”的所有变换的步骤,即打表预处理。

  这里要注意就是最后输出的时候,由于我们求得是逆序,所以要倒序输出,倒序输出的时候要注意'u'、'd'、'l'、'r'都应该颠倒过来,比如说你从A状态向上变换为B状态,这时你从B变为A就要向下变换。

  这里哈希还是用的康托展开,这个问题我在上一篇博客中有提到过。

BFS + 打表:

#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <cmath>
#include <string>
#include <string.h>
#include <algorithm>
using namespace std;
#define LL __int64
#define eps 1e-8
#define INF 1e8
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int MOD = ;
const int maxn = ;
bool vis[maxn];
string ans[maxn];
int fac[]={ , , , , , , , , , }; int Cantor(string str)
{
int ret = ;
int n = str.size();
for(int i = ; i < n ; i++) {
int cnt = ;
for(int j = i ; j < n ; j++)
if(str[j] < str[i])
cnt++;
ret += cnt * fac[n - i - ];
}
return ret;
}
void move_Up(string &str , int pos)
{
swap(str[pos] , str[pos - ]);
}
void move_Down(string &str , int pos)
{
swap(str[pos] , str[pos + ]);
}
void move_Left(string &str , int pos)
{
swap(str[pos] , str[pos - ]);
}
void move_Right(string &str , int pos)
{
swap(str[pos] , str[pos + ]);
}
void BFS(string start)
{
memset(vis , , sizeof(vis));
queue <string> que;
que.push(start);
int x = Cantor(start);
vis[x] = ;
ans[x] = "";
int pos;
while(!que.empty()) {
string u = que.front();
que.pop();
int i = Cantor(u);
for(pos = ; pos < ; pos++)
if(u[pos] == 'x')
break; if(pos > ) {
string tmp = u;
move_Up(tmp , pos);
int k = Cantor(tmp);
if(!vis[k]) {
vis[k] = ;
que.push(tmp);
ans[k] = ans[i] + 'u';
}
}
if(pos < ) {
string tmp = u;
move_Down(tmp , pos);
int k = Cantor(tmp);
if(!vis[k]) {
vis[k] = ;
que.push(tmp);
ans[k] = ans[i] + 'd';
}
}
if(pos % != ) {
string tmp = u;
move_Left(tmp , pos);
int k = Cantor(tmp);
if(!vis[k]) {
vis[k] = ;
que.push(tmp);
ans[k] = ans[i] + 'l';
}
}
if(pos % != ) {
string tmp = u;
move_Right(tmp , pos);
int k = Cantor(tmp);
if(!vis[k]) {
vis[k] = ;
que.push(tmp);
ans[k] = ans[i] + 'r';
}
}
}
}
int main()
{
char ch[];
string start = "12345678x";
BFS(start);
while(gets(ch))
{
string str = "";
for(int i = ; ch[i] != '\0' ; i++) {
if(ch[i] == ' ')
continue;
else
str += ch[i];
}
int k = Cantor(str);
if(vis[k]) {
for(int i = ans[k].size() - ; i >= ; i--) {
if(ans[k][i] == 'u')
putchar('d');
else if(ans[k][i] == 'd')
putchar('u');
else if(ans[k][i] == 'l')
putchar('r');
else
putchar('l');
}
puts("");
} else {
cout << "unsolvable" << endl;
}
}
return ;
}

HDU1043 八数码(BFS + 打表)的更多相关文章

  1. hdu-1043(八数码+bfs打表+康托展开)

    参考文章:https://www.cnblogs.com/Inkblots/p/4846948.html 康托展开:https://blog.csdn.net/wbin233/article/deta ...

  2. 紫书p199 八数码(BFS,hash)

    八数码问题  紫书上的简单搜索  渣渣好久才弄懂 #include<cstdio> #include<cstring> using namespace std; const i ...

  3. code1225 八数码Bfs

    Bfs搜索 1.把棋盘直接作为状态: #include<iostream> #include<cstring> #include<queue> #include&l ...

  4. POJ1077 八数码 BFS

    BFS 几天的超时... A*算法不会,哪天再看去了. /* 倒搜超时, 改成顺序搜超时 然后把记录路径改成只记录当前点的操作,把上次的位置记录下AC..不完整的人生啊 */ #include < ...

  5. POJ1077&&HDU1043(八数码,IDA*+曼哈顿距离)

    Eight Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 30127   Accepted: 13108   Special ...

  6. luogu_1379 八数码难题

    八数码-->BFS+set #include<iostream> #include<cstdlib> #include<cstdio> #include< ...

  7. HDU-1043 Eight八数码 搜索问题(bfs+hash 打表 IDA* 等)

    题目链接 https://vjudge.net/problem/HDU-1043 经典的八数码问题,学过算法的老哥都会拿它练搜索 题意: 给出每行一组的数据,每组数据代表3*3的八数码表,要求程序复原 ...

  8. hdu1043 经典的八数码问题 逆向bfs打表 + 逆序数

    题意: 题意就是八数码,给了一个3 * 3 的矩阵,上面有八个数字,有一个位置是空的,每次空的位置可以和他相邻的数字换位置,给你一些起始状态 ,给了一个最终状态,让你输出怎么变换才能达到目的. 思路: ...

  9. poj 1077-Eight(八数码+逆向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. Java 概述及安装使用

    Java是什么 概述 java是一种面向对象编程语言,不过经过多年的发展,现在已经演变为了一套强大的技术体系.Java设计者们将Java划分为3种结构独立但却彼此依赖的技术体系分支,它们分别对应着不同 ...

  2. linux添加软件的service start/stop快捷服务(简单版)

    首先我们先需要一款软件,例如“apache” 安装解压至相应目录“/home/aaa/apache” 开始操作:进入“/etc/init.d/”中,新建一个service服务运行脚本“tomcat”, ...

  3. sed命令使用

    创建模板文件 # cat >> example.txt <<"EOF" TeSt Test test EOF 测试过程中均不使用-i参数避免模板文件内容被修 ...

  4. webpack@3.6.0(2) -- css及图片相关问题

    本篇内容 css3前缀处理postcss 消除未使用的css部分 图片处理 css分离和分离后的图片处理 css3前缀处理postcss cnpm i -D postcss-loader autopr ...

  5. 洛谷P3966 [TJOI2013]单词(后缀自动机)

    传送门 统计单词出现次数……为啥大家都是写AC自动机的嘞……明明后缀自动机也能做的说…… 统计出现次数这个就直接按长度排序然后做个dp就好,这是SAM的板子的要求啊,不提了 然后考虑怎么让所有串之间隔 ...

  6. print和sys.stdout

    print print语句执行的操作是一个写操作,把我们从外设输入的数据写到了stdout流,并进行了一些特定的格式化.和文件方法不同,在执行打印操作是,不需要将对象转换为字符串(print已经帮我们 ...

  7. CPU使用情况检测

    改编自:https://blog.csdn.net/Yan_Chou/article/details/80456995 检测命令整理: dd iotop df top psiostatvmstatne ...

  8. 洛谷P2068 统计和

    题目描述 给定一个长度为\(n(n \leq 100000)\),初始值都为\(0\)的序列,\(x(x \leq 10000)\)次的修改某些位置上的数字,每次加上一个数,然后提出\(y (y \l ...

  9. day22作业详解

    1.面向对象作业1 2.作业详解 点击查看详细内容 #1. class Li(object): def func1(self): print('in func1') obj = Li() obj.fu ...

  10. Anywhere 随启随用的静态文件服务器

    三江建材官网项目 写nodeJs系列的文章都是因为这一个项目 第一天,搭建项目环境 记录心情: 首先,在写这个项目的时候,我很无助,只是拿到了设计稿,还有一个指导人,平常会很忙,只有在休闲的时候才能动 ...