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 ...
随机推荐
- [leetcode]_Remove Duplicates from Sorted Array II
题目:一个有序数组,要求保证数组中的每个元素不能超过2个. 输入:A = [1,1,1,2,2,3] 输出:length = 5, and A is now [1,1,2,2,3] 思路:双指针 ...
- PHP数组操作大全
<?php /** * File: phpstudy : array_test.php * Created by PhpStorm. * User: IhMfLy Pheonix@jtv-070 ...
- 学习c语言的第9天
#include <stdio.h> int main() { float sum=0,wage=0; int i=1; int num; printf("+++平均工资统计程序 ...
- jQuery编写的一款兼容IE6的图片轮播幻灯片
jQuery编写的一款兼容IE6的图片轮播幻灯片,很不错的一款jquery特效.大家可以下载下来研究研究. 每隔几秒就自动切换一波图片,此效果兼容性还做的不错,适合居多的浏览器. 适用浏览器:IE6. ...
- (转)Arcgis API常用接口调用方法
var map, navToolbar, editToolbar, tileLayer, toolbar;//var mapBaseUrl = "http://localhost:8399/ ...
- SQL Server 基础:Join用法
Join(麻蛋 废话不多说 有图有真相) 测试数据脚本 CREATE TABLE Atable ( S# INT, Sname ), Sage INT, Sfrom ) ) insert into ...
- scp 跨机远程拷贝
scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器. 命令格式: scp [参数] [原路径] [目标路径] ...
- RMAN 报:ORA-19504 ORA-27038
在itpub中看到下面的问题: oracle 10g备份脚本如下run{allocate channel d1 device type disk MAXPIECESIZE=100M;crosschec ...
- Cygwin ssh服务配置 (SecureCRT连接Cygwin配置)
1.运行ssh-host-config 这里需要注意的是标红部分,输入的用户名或密码要符合计算机的用户名或密码策略(尤其是公司有权限限制的电脑). $ ssh-host-config *** Quer ...
- SaaS应用“正益工作”发布,为大中型企业轻松构建移动门户
6月24日,以“平台之上,应用无限”为主题的2016 AppCan移动开发者大会,在北京国际会议中心隆重举行,逾1500名移动开发者一起见证了此次大会盛况. 会上,在专家领导.技术大咖.移动开发者的共 ...