HDU1043 Eight(BFS)
Time Limit:5000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
Description
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
1 2 3
x 4 6
7 5 8
is described by this list:
1 2 3 x 4 6 7 5 8
Output
Sample Input
Sample Output
#include<cstdio>
#include<string>
#include<queue>
#include<cstring>
using namespace std;
struct node
{
int t[][],x,y,Can;
int Last_Can,dir;
} St[];
int fac[]= {,,,,,,,,};
//康托展开的数组
//康托展开就是把一组数据按照字典序排列的那组数据的序号 int vis[];
queue<int> Q;
char dr[]="rlud";
int dx[]= {,,,-};
int dy[]= {-,,,};
//方向数组,与实际的方向相反,因为是逆向操作
int Cantor(int *t)//对一组数据求康拓值
{
int rev=;
for(int i=; i<; i++)
{
int counted=;
for(int j=i+; j<; j++)
if(t[i]>t[j]) counted++;
rev+=counted*fac[-i];
}
return rev;
}
bool check(int x,int y) //检查这个点是不是在矩形内
{
return x>=&&x<&&y>=&&y<;
}
void solve()//bfs求出所有的情况,并储存下来父节点
{
while(!Q.empty()) Q.pop();
node st;
st.x=st.y=;
int s[][]= {,,,,,,,,};
int t[];
for(int i=; i<; i++)
for(int j=; j<; j++)
t[i*+j]=s[i][j];
for(int i=; i<; i++)
for(int j=; j<; j++)
st.t[i][j]=s[i][j];
int StCan=Cantor(t);
st.Can=StCan;
st.Last_Can=-;
st.dir=-;
memset(vis,,sizeof vis);
vis[StCan]=;
St[StCan]=st;
Q.push(StCan);
int Sum=;
while(!Q.empty())
{
Sum++;
int TempCan=Q.front();
Q.pop();
for(int i=; i<; i++)
{
node e=St[TempCan];
int curx=e.x+dx[i];
int cury=e.y+dy[i];
if(check(curx,cury))
{
int c=e.t[curx][cury];
e.t[curx][cury]=e.t[e.x][e.y];
e.t[e.x][e.y]=c;
e.x=curx;
e.y=cury;
int t[];
for(int i=; i<; i++)
for(int j=; j<; j++)
t[i*+j]=e.t[i][j];
e.Can=Cantor(t);
e.Last_Can=TempCan;
e.dir=i;
if(!vis[e.Can])
{
vis[e.Can]=;
St[e.Can]=e;
Q.push(e.Can);
}
}
}
}
}
int main()
{
char c[];
int t[],x=;
solve();
while(scanf("%s",c)!=EOF)
{
if(c[]=='x') c[]='';
t[]=c[]-'';
for(int i=;i<;i++)
{
scanf("%s",c);
if(c[]=='x') c[]='';
t[i]=c[]-'';
}
int AnsCan=Cantor(t);
if(vis[AnsCan])
{
int p=AnsCan;
while(St[p].Last_Can+)
{
printf("%c",dr[St[p].dir]);
p=St[p].Last_Can;
}
printf("\n");
}
else
printf("unsolvable\n");
}
return ;
}
Eight
HDU1043 Eight(BFS)的更多相关文章
- Eight HDU-1043 (bfs)
Eight Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- HDU-1043 Eight八数码 搜索问题(bfs+hash 打表 IDA* 等)
题目链接 https://vjudge.net/problem/HDU-1043 经典的八数码问题,学过算法的老哥都会拿它练搜索 题意: 给出每行一组的数据,每组数据代表3*3的八数码表,要求程序复原 ...
- hdu-1043 bfs+康拓展开hash
因为是计算还原成一种局面的最短步骤,应该想到从最终局面开始做bfs,把所有能到达的情况遍历一遍,把值存下来. bfs过程中,访问过的局面的记录是此题的关键,9*9的方格在计算过程中直接存储非常占内存. ...
- hdu-1043(八数码+bfs打表+康托展开)
参考文章:https://www.cnblogs.com/Inkblots/p/4846948.html 康托展开:https://blog.csdn.net/wbin233/article/deta ...
- 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 + 打表. 经典八数码问题,传说此题不做人生不完整,关于八数码的八境界 ...
- hdu1043 经典的八数码问题 逆向bfs打表 + 逆序数
题意: 题意就是八数码,给了一个3 * 3 的矩阵,上面有八个数字,有一个位置是空的,每次空的位置可以和他相邻的数字换位置,给你一些起始状态 ,给了一个最终状态,让你输出怎么变换才能达到目的. 思路: ...
- ACM/ICPC 之 BFS-广搜进阶-八数码(经典)(POJ1077+HDU1043)
八数码问题也称为九宫问题.(本想查查历史,结果发现居然没有词条= =,所谓的历史也就不了了之了) 在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同.棋盘上还有一个 ...
- 【HDU - 1043】Eight(反向bfs+康托展开)
Eight Descriptions: 简单介绍一下八数码问题:在一个3×3的九宫格上,填有1~8八个数字,空余一个位置,例如下图: 1 2 3 4 5 6 7 8 在上图中,由于右下角位置是空的 ...
随机推荐
- [原]此程序专用来说明C++模板的用法
#include using namespace std; //此程序专用来说明模版的使用 template void swap1(T& a,T& b){ T temp=a; ...
- 2016届百度实习生前端笔试题上海卷a
1.写出javascript运行结果:alert(‘5’+5); 结果:alert()函数中不能进行算术运算或字符串拼接,故不会弹出对话框. 2.写出javascript运行结果:for(var ...
- [XMPP]iOS聊天软件学习笔记[三]
今天做了好友界面,其实xmpp内部已经写好很多扩展模块,所以使用起来还是很方便的 开发时间:五天(工作时间) 开发工具:xcode6 开发平台:iOS8 XMPP框架:XMPPFramework gi ...
- window7下statsvn统计代码量
下载statsvn:http://www.statsvn.org/ 将下载后的statsvn.jar放到d:\svn目录下; 打开cmd窗口切换到需要统计代码的项目目录如:d:\project\web ...
- Axure快捷键大全
基本快捷键: 打开:Ctrl + O 新建:Ctrl + N 保存:Ctrl + S 退出:Alt + F4 打印:Ctrl + P 查找:Ctrl + F 替换:Ctrl + H 复制:Ctrl + ...
- Single Number 解答
Question Given an array of integers, every element appears twice except for one. Find that single on ...
- python使用post登陆电子科大信息门户并保存登陆后页面
python使用post登陆电子科大信息门户并保存登陆后页面 作者:vpoet mail:vpoet_sir@163.com #coding=utf-8 import HTMLParser impor ...
- 《火球——UML大战需求分析》(第3章 分析业务模型-类图)——3.8 小结与练习
摘要:类图(Class Diagram)可能是用得最多的一种UML图.类图的基本语法并不复杂,你可能最多学习两三天就可以掌握,然而要真正做到活用类图则可能需要几年的功力.类图是锻炼面向对象分析(OOA ...
- Python 面向对象基础
面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 面向过程的程序设计把计算机 ...
- java连接oracle数据库详细代码
详细代码: import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;imp ...