hdu 1043 Eight 经典八数码问题
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043
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.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
#define inf 0x7fffffff
using namespace std;
const int maxn=;
const int M = +; struct node
{
int mase[][];
int x,y;
int f,g,h;
int flag;
friend bool operator < (node a,node b)
{
return a.f > b.f;
}
}start,tail;
int pre[M],v[M]; char str[]={'u','d','l','r' };
int Can[]={,,,,,,,, };
const int destination=;
int Cantor(node cur) ///康托展开
{
int an[],k=;
for (int i= ;i< ;i++)
for (int j= ;j< ;j++)
an[k++]=cur.mase[i][j];
int sum=;
for (int i= ;i< ;i++)
{
int k=;
for (int j=i+ ;j< ;j++)
if (an[i]>an[j]) k++;
sum += k*Can[-i-];
}
return sum+;
} int is_ok(node an) ///判断此时奇偶性
{
int a[],k=;
for (int i= ;i< ;i++)
for (int j= ;j< ;j++)
a[k++]=an.mase[i][j];
int sum=;
for (int i= ;i<k ;i++) if (a[i]!=)
for (int j= ;j<i ;j++)
if (a[j]!= && a[j]>a[i]) sum ++ ;
if (sum&) return ;
return ;
} void print(node cur)
{
string ans;
int sum=destination;
while (pre[sum] != -)
{
switch (v[sum]) {
case : ans += str[];break;
case : ans += str[];break;
case : ans += str[];break;
case : ans += str[];break;
}
sum=pre[sum];
}
int len=ans.size() ;
for (int i=len- ;i>= ;i--) putchar(ans[i]);
return ;
} pair<int,int> pii[];
int getH(node cur)
{
int r=,c=;
for (int i= ;i<= ;i++)
{
pii[i%].first=r ;
pii[i%].second=c;
c++;
if (c==) {r++;c=; }
}
int sum=;
for (int i= ;i< ;i++)
{
for (int j= ;j< ;j++)
{
int u=cur.mase[i][j];
sum += abs(pii[u].first-i)+abs(pii[u].second-j);
}
}
return sum;
} int vis[M];
int an[][]={-,, ,, ,-, , };
void A_star(node cur)
{
priority_queue<node> Q;
cur.g= ;cur.h=getH(cur);
cur.f=cur.g + cur.h ;
cur.flag=-;
Q.push(cur);
memset(vis,-,sizeof(vis));
memset(pre,-,sizeof(pre));
memset(v,-,sizeof(v));
vis[Cantor(cur) ]=;
while (!Q.empty())
{
cur=Q.top() ;Q.pop() ;
if (Cantor(cur)==destination)
{
// cout<<cur.g<<endl;
// for (int i=0 ;i<3 ;i++)
// {
// for (int j=0 ;j<3 ;j++)
// cout<<cur.mase[i][j]<<" ";
// cout<<endl;
// }
///输出序列
print(cur);
return ;
}
for (int i= ;i< ;i++)
{
tail.x=cur.x+an[i][];
tail.y=cur.y+an[i][];
int x=cur.x ,y=cur.y ;
for (int u= ;u< ;u++)
for (int v= ;v< ;v++)
tail.mase[u][v]=cur.mase[u][v];
if (tail.x<||tail.x>=||tail.y<||tail.y>=) continue;
swap(tail.mase[tail.x][tail.y],tail.mase[x][y]);
int sum=Cantor(tail);
if (vis[sum]==-)
{
if (is_ok(tail)==) continue;
vis[sum]=;
tail.g=cur.g+;
tail.h=getH(tail);
tail.f=tail.g+tail.h;
if (tail.x==x+) tail.flag=;
else if (tail.x==x-) tail.flag=;
else if (tail.y==y-) tail.flag=;
else if (tail.y==y+) tail.flag=;
pre[sum]=Cantor(cur);
v[sum]=i;
Q.push(tail);
}
}
}
return ;
} int main()
{
char str[];
while (gets(str))
{
int r=,c=;
int len=strlen(str);
int ok=;
for (int i= ;i<len ;i++)
{
if (str[i]>='' && str[i]<='')
{
start.mase[r][c]=str[i]-'';
c++;
if (c==) {r++;c=; }
}
else if (str[i]=='x')
{
start.mase[r][c]=;
start.x=r ;start.y=c ;
c++;
if (c==) {r++;c=; }
}
}
int sum=Cantor(start);
if (sum==destination) {printf("\n");continue; }
if (is_ok(start)==) {printf("unsolvable\n");continue; }
A_star(start);
printf("\n");
}
return ;
}
hdu 1043 Eight 经典八数码问题的更多相关文章
- HDU 1043 Eight(八数码)
HDU 1043 Eight(八数码) 00 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Problem Descr ...
- hdu 1043(经典搜索)
题意: 给你一个初始的图,然后每次输入一个图,要求移动x最小的步数达到和初始图一样,输出路径 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 ...
- HDU 1043 Eight 【经典八数码输出路径/BFS/A*/康托展开】
本题有写法好几个写法,但主要思路是BFS: No.1 采用双向宽搜,分别从起始态和结束态进行宽搜,暴力判重.如果只进行单向会超时. No.2 采用hash进行判重,宽搜采用单向就可以AC. No.3 ...
- HDU1043 八数码(BFS + 打表)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 , 康托展开 + BFS + 打表. 经典八数码问题,传说此题不做人生不完整,关于八数码的八境界 ...
- hdu 1043 Eight(双向bfs)
题意:经典八数码问题 思路:双向bfs ps:还有a*算法(还不会)等解法. 代码: #include<iostream> #include<stdio.h> #include ...
- HDU 1043 Eight 八数码问题 A*算法(经典问题)
HDU 1043 Eight 八数码问题(经典问题) 题意 经典问题,就不再进行解释了. 这里主要是给你一个状态,然后要你求其到达\(1,2,3,4,5,6,7,8,x\)的转移路径. 解题思路 这里 ...
- Hdu 1043 Eight (八数码问题)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1043 题目描述: 3*3的格子,填有1到8,8个数字,还有一个x,x可以上下左右移动,问最终能否移动 ...
- Eight POJ - 1077 HDU - 1043 八数码
Eight POJ - 1077 HDU - 1043 八数码问题.用hash(康托展开)判重 bfs(TLE) #include<cstdio> #include<iostream ...
- HDU 1043 Eight (BFS·八数码·康托展开)
题意 输出八数码问题从给定状态到12345678x的路径 用康托展开将排列相应为整数 即这个排列在全部排列中的字典序 然后就是基础的BFS了 #include <bits/stdc++.h ...
随机推荐
- PeopleSoft登录流程
1.初始化连接.App Server从配置文件中获得connect ID和user ID进行数据库初始化连接. 2.查询数据库中与安全相关的表信息connect ID被验证以后,AppServer查询 ...
- 使用虚拟机在ubuntu下搭建mongoDB开发环境和简单增删改查操作
最近在折腾mongodb和nodejs,在imooc上找了一个mongodb的入门教程,跟着里面一步一步的走,下面记录下我操作的步骤和遇到的问题. 课程地址:http://www.imooc.com/ ...
- 2013/8/28 JS+HTML 三级省市区联动
var mp = ["安徽","北京","福建","甘肃","广东","广西", ...
- MVC MVVM Knockout 常遇问题总结
1.模板绑定(使用插件jquery.tmpl) var ViewModel={Product:ko.observable()} <div data-bind="template:{na ...
- asp.net mvc razor html encoding
HTML Encoding 为了跨站点的脚本攻击,Razor 语法会直接将脚本代码编码输出. @{string message = "<script>alert('haacked ...
- openerp 经典收藏 记录规则 – 销售只能看到自己的客户,经理可以看到全部(转载)
记录规则 – 销售只能看到自己的客户,经理可以看到全部 原文地址:http://cn.openerp.cn/record_rule/ OpenERP中的权限管理有四个层次: 菜单级别: 即,不属于指定 ...
- 使用Android Studio开发J2SE项目方法
0.前言 最近因为要为项目开发一个底层的Java应用,所以非常偶然的遇到了这样一个问题,过去Eclipse有Java Project而现在手头使用Android Studio并不能直接建立Java应用 ...
- VMware共享目录设置
1.保证虚拟机中已经成功安装了 VMware Tools (非常关键) 2.打开VMware,并使虚拟机处于关机状态,然后请按图中箭头所示进行操作 这样就大功告成了,此时进入虚拟机, 执行命令 cd ...
- JavaScript高级程序设计之函数
函数实际上是对象,每个函数都是Function类型的实例. 函数是引用类型. 函数名实际上是一个指向函数对象的指针,不会与某个函数绑定. // 这种写法更能表达函数的本质 var sum = func ...
- VS2010遇到_WIN32_WINNT宏定义问题
最近拿到一个别人的工程,是使用VS.net创建的,而我的机器上只有vs2010,于是用自带的转换工具将它转换成vs2010的工程,转换之前我就很担心,怕转换完后会出问题,但是没有办法,我实在是不想再安 ...