http://acm.hdu.edu.cn/showproblem.php?pid=1043

Eight

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 30907    Accepted Submission(s): 8122
Special Judge

Problem Description
The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've seen it. It is constructed with 15 sliding tiles, each with a number from 1 to 15 on it, and all packed into a 4 by 4 frame with one tile missing. Let's call the missing tile 'x'; the object of the puzzle is to arrange the tiles so that they are ordered as:

 1  2  3  4
5 6 7 8
9 10 11 12
13 14 15 x

where the only legal operation is to exchange 'x' with one of the tiles with which it shares an edge. As an example, the following sequence of moves solves a slightly scrambled puzzle:

 1  2  3  4     1  2  3  4     1  2  3  4     1  2  3  4
5 6 7 8 5 6 7 8 5 6 7 8 5 6 7 8
9 x 10 12 9 10 x 12 9 10 11 12 9 10 11 12
13 14 11 15 13 14 11 15 13 14 x 15 13 14 15 x
r-> d-> r->

The letters in the previous row indicate which neighbor of the 'x' tile is swapped with the 'x' tile at each step; legal values are 'r','l','u' and 'd', for right, left, up, and down, respectively.

Not all puzzles can be solved; in 1870, a man named Sam Loyd was famous for distributing an unsolvable version of the puzzle, and 
frustrating many people. In fact, all you have to do to make a regular puzzle into an unsolvable one is to swap two tiles (not counting the missing 'x' tile, of course).

In this problem, you will write a program for solving the less well-known 8-puzzle, composed of tiles on a three by three 
arrangement.

 
Input
You will receive, several descriptions of configuration of the 8 puzzle. One description is just a list of the tiles in their initial positions, with the rows listed from top to bottom, and the tiles listed from left to right within a row, where the tiles are represented by numbers 1 to 8, plus 'x'. For example, this puzzle

1 2 3 
x 4 6 
7 5 8 
is described by this list:

1 2 3 x 4 6 7 5 8

 
Output
You will print to standard output either the word ``unsolvable'', if the puzzle has no solution, or a string consisting entirely of the letters 'r', 'l', 'u' and 'd' that describes a series of moves that produce a solution. The string should include no spaces and start at the beginning of the line. Do not print a blank line between cases.
 
Sample Input
2 3 4 1 5 x 7 6 8
 
Sample Output
ullddrurdllurdruldr
题解:裸的康拓展开
使用康拓展开对全排列进行hash,然后使用bfs从末状态开始跑,跑到的状态都是有解的状态,否则输入的初状态无解,在bfs过程记录这一步的下一步即可。
 #include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int qwq[];
char sss[];
int vv[];
bool v[];
int f0;
int counter(string s){
int sum=;
for(int i=;i<=;i++){
qwq[i]=qwq[i-]*i;
}
for(int i=;i<;i++){
int tt=;
for(int j=i+;j<;j++){
if(s[j]<s[i]){
tt++;
}
}
sum+=qwq[-i]*tt;
}
return sum;
}
queue<string>pq;
void bfs(){
while(!pq.empty())pq.pop();
string s0="";
pq.push(s0);
f0=counter(s0);
v[f0]=;
while(!pq.empty()){
string aa=pq.front();pq.pop();
int fs=counter(aa);
//if(fs==76346)cout <<aa<<endl;
for(int i=;i<aa.size();i++){
if(aa[i]==''){
if(i%==){
string bb=aa;
bb[i]=bb[i+];
bb[i+]='';
int f=counter(bb);
if(!v[f]){
v[f]=;
sss[f]='l';
vv[f]=fs;
pq.push(bb);
}
if(i!=){
string cc=aa;
cc[i]=cc[i+];
cc[i+]='';
int f=counter(cc);
if(!v[f]){
v[f]=;
vv[f]=fs;
sss[f]='u';
pq.push(cc);
}
}
if(i!=){
string dd=aa;
dd[i]=dd[i-];
dd[i-]='';
int f=counter(dd);
if(!v[f]){
v[f]=;
vv[f]=fs;
sss[f]='d';
pq.push(dd);
}
}
}
else if(i%==){
string bb=aa;
bb[i]=bb[i+];
bb[i+]='';
int f=counter(bb);
if(!v[f]){
v[f]=;
vv[f]=fs;
sss[f]='l';
pq.push(bb);
}
string cc=aa;
cc[i]=cc[i-];
cc[i-]='';
f=counter(cc);
if(!v[f]){
v[f]=;
vv[f]=fs;
sss[f]='r';
pq.push(cc);
}
if(i!=){
string cc=aa;
cc[i]=cc[i+];
cc[i+]='';
int f=counter(cc);
if(!v[f]){
v[f]=;
vv[f]=fs;
sss[f]='u';
pq.push(cc);
} }
if(i!=){
string dd=aa;
dd[i]=dd[i-];
dd[i-]='';
int f=counter(dd);
if(!v[f]){
v[f]=;
vv[f]=fs;
sss[f]='d';
pq.push(dd);
}
}
}
else{
string bb=aa;
bb[i]=bb[i-];
bb[i-]=''; int f=counter(bb);
// if(fs==76346)
//cout <<f<<" "<<endl;
if(!v[f]){
v[f]=;
vv[f]=fs;
sss[f]='r';
pq.push(bb);
}
if(i!=){
string cc=aa;
cc[i]=cc[i+];
cc[i+]='';
int f=counter(cc); if(!v[f]){
v[f]=;
vv[f]=fs;
sss[f]='u';
pq.push(cc);
}
}
if(i!=){
string dd=aa;
dd[i]=dd[i-];
dd[i-]='';
int f=counter(dd);
if(!v[f]){
v[f]=;
vv[f]=fs;
sss[f]='d';
pq.push(dd);
}
}
}
}
}
}
}
void init(){
qwq[]=qwq[]=;
for(int i=;i<=;i++){
qwq[i]=qwq[i-]*i;
}
}
int main(){
init();
bfs();
char aa[];
char bb[];
//while(scanf("%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",aa[0],aa[1],aa[2],aa[3],aa[4],aa[5],
// aa[6],&aa[7],&aa[8],)){
while(gets(aa)){
if(aa[]=='\0')break;
int tot=;
int len=strlen(aa);
for(int i=;i<len;i++){
if((aa[i]>=''&&aa[i]<='')){
bb[tot++]=aa[i];
}
if(aa[i]=='x'){
bb[tot++]='';
}
}
bb[tot]='\0';
int f=counter(bb);
// cout << f<<" "<<bb<<endl;
//cout <<f<<endl;46103
if(!v[f]){
printf("unsolvable\n");
}
else{
for(int i = f ; i != f0 ; i=vv[i]){
// cout << vv[<<endl;
printf("%c",sss[i]);
//system("pause");
}
printf("\n");
}
}
return ;
}

【HDOJ1043】【康拓展开+BFS】的更多相关文章

  1. hdu1430 魔板(康拓展开 bfs预处理)

    魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...

  2. ACM/ICPC 之 BFS(离线)+康拓展开 (HDU1430-魔板)

    魔板问题,一道经典的康拓展开+BFS问题,为了实现方便,我用string类来表示字符串,此前很少用string类(因为不够高效,而且相对来说我对char数组的相关函数比较熟),所以在这里也发现了很多容 ...

  3. bnuoj 1071 拼图++(BFS+康拓展开)

    http://www.bnuoj.com/bnuoj/problem_show.php?pid=1071 [题意]:经过四个点的顺逆时针旋转,得到最终拼图 [题解]:康拓展开+BFS,注意先预处理,得 ...

  4. hdoj1043 Eight(逆向BFS+打表+康拓展开)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 思路: 由于自己对康拓展开用的太少,看到这个题没想到康拓展开,最开始打算直接转换为数字,但太占内 ...

  5. ACM/ICPC 之 BFS(离线)+康拓展开(TSH OJ-玩具(Toy))

    祝大家新年快乐,相信在新的一年里一定有我们自己的梦! 这是一个简化的魔板问题,只需输出步骤即可. 玩具(Toy) 描述 ZC神最擅长逻辑推理,一日,他给大家讲述起自己儿时的数字玩具. 该玩具酷似魔方, ...

  6. hdu 1043 pku poj 1077 Eight (BFS + 康拓展开)

    http://acm.hdu.edu.cn/showproblem.php?pid=1043 http://poj.org/problem?id=1077 Eight Time Limit: 1000 ...

  7. 九宫重拍(bfs + 康拓展开)

    问题描述 如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着.与空格子相邻的格子中的卡片可以移动到空格中.经过若干次移动,可以形成第二个图所示的局面. 我们把第一个图的局面记为:12 ...

  8. 8数码,欺我太甚!<bfs+康拓展开>

    不多述,直接上代码,至于康拓展开,以前的文章里有 #include<iostream> #include<cstdio> #include<queue> using ...

  9. 【算法系列学习三】[kuangbin带你飞]专题二 搜索进阶 之 A-Eight 反向bfs打表和康拓展开

    [kuangbin带你飞]专题二 搜索进阶 之 A-Eight 这是一道经典的八数码问题.首先,简单介绍一下八数码问题: 八数码问题也称为九宫问题.在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的 ...

随机推荐

  1. VIM编辑配置文件基本操作

    vim  /etc/apt/sources.list 按insert键进入编辑状态 编辑完成以后按ESC退出编辑状态 输入 ":"进入命令状态,常用命令: 1.W:write ,写 ...

  2. 老毛桃制作装机版u盘

    启动盘准备工作: ① 老毛桃官网首页下载老毛桃v9.3装机版u盘启动盘制作工具安装到电脑上: ② 准备一个容量大在4G以上并能够正常使用的u盘. 第一步 到老毛桃官网中下载老毛桃v9.3安装包到系统桌 ...

  3. MySQL远程登陆

    mysql:连接数据库 1.连接到本机上的MYSQL 命令:mysql -u [username] -p username:用户名 命令示例:mysql -u root -p,回车后提示你输密码. 2 ...

  4. java基础巩固之java实现文件上传

      对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用Servlet获取上传文件的输入流然后再解析里面的请求参数是比较麻烦,所以一般选择采用apache的开源工具com ...

  5. vue-12-渲染函数 & JSX

    render() Vue.component('anchored-heading', { render: function (createElement) { return createElement ...

  6. Linux命令----su(切换用户)以及passwd(修改用户密码)

    一.su命令登录root 用户在使用telnet命令可以远程登录,但不可以登录root,这样就需要使用su命令来登录root用户. telnet登录(不能登录root)--- 1.启动终端 输入 te ...

  7. 谈谈你对Java多线程的理解以及多线程的实现方式

    说线程之前先说进程,何为进程?进程就是正在进行中的程序.比如电脑同时在运行QQ进程.cmd进程.wps进程.飞秋进程等.在某一时刻,CPU只能执行一个程序,只是在做快速切换,我们肉眼看不出来. 比如: ...

  8. TLS反调试

    0x01 TLS反调试简介 TLS(Thread Local Storage)原本的目的是解决多线程程序中变量同步的问题.线程本身有独立于其他线程的栈空间,因此线程中的局部变量不用考虑同步问题.多线程 ...

  9. ui-router ng-router

    开发中常用ui-router来设置路由: ui-router使用很简单,延续了之前ngRoute的特点. 1.首先得注入ui.router模块. 接下来就是简单的配置 2.$stateProvider ...

  10. Bootstrap中模态框多层嵌套时滚动条问题

    在使用Bootstrap中模态框过程中,如果出现多层嵌套的时候,如打开模态框A,然后在A中打开模态框B,在关闭B之后,如果A的内容比较多,滚动条会消失,而变为Body的滚动条,这是由于模态框自带的遮罩 ...