您的位置:首页 > 其它

HDU 1043 Eight A*算法+康托展开

2017-05-27 16:37 197 查看
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.
InputYou 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
OutputYou 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

 跟小时候玩的那个小拼图的玩具差不多= =~
但是好恐怖啊QAQ
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
const int MAXN=4e5+10;
int ha[9]={1,1,2,6,24,120,720,5040,40320};//hash的权值
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
char d[]="udlr";
int vis[MAXN];
struct node
{
int f[3][3];
int x,y;
int g,h;//优先队列的两个关键字
int num;
bool operator<(const node a)const
{
return h+g>a.h+a.g;
}
};
struct path
{
int pre;
char ch;
}p[MAXN];
void Print(int x)
{
if(p[x].pre==-1) return ;
Print(p[x].pre);
printf("%c",p[x].ch);
}
int get_hash(struct node e)//康托展开,压缩
{
int a[9];
int i,j;
int k=0;
int ans=0;
for(i=0;i<=2;i++)
{
for(j=0;j<=2;j++)
{
a[k++]=e.f[i][j];
}
}
for(i=0;i<=8;i++)
{
k=0;
for(j=0;j<=i-1;j++)
{
if(a[j]>a[i])k++;
}
ans+=ha[i]*k;
}
return ans;
}
int get_h(struct node e)
{
int i,j;
int ans=0;
for(i=0;i<=2;i++)
{
for(j=0;j<=2;j++)
{
if(e.f[i][j])
ans+=abs(i-(e.f[i][j]-1)/3)+abs(j-(e.f[i][j]-1)%3);
}
}
return ans;
}
void A_star(struct node e)
{
memset(vis,0,sizeof(vis));
int i,j,k;
struct node a,b;
for(i=0;i<=8;i++)
a.f[i/3][i%3]=(i+1)%9;
int ans=get_hash(a);
e.num=get_hash(e);
e.g=0;
e.h=get_h(e);
vis[e.num]=1;
p[e.num].pre=-1;
if(e.num==ans)
{
printf("\n");
return ;
}
priority_queue<struct node>q;
q.push(e);
while(!q.empty())
{
e=q.top();
q.pop();
for(i=0;i<=3;i++)
{
int xx=e.x+dir[i][0];
int yy=e.y+dir[i][1];
if(xx>=0&&xx<=2&&yy>=0&&yy<=2)
{
a=e;
swap(a.f[e.x][e.y],a.f[xx][yy]);
k=get_hash(a);
if(vis[k])continue;
vis[k]=1;
a.num=k;
a.x=xx;
a.y=yy;
a.g++;
a.h=get_h(a);
p[k].pre=e.num;
p[k].ch=d[i];
if(k==ans)
{
Print(k);
printf("\n");
return ;
}
q.push(a);
}
}
}
}
int main()
{
char a[30];
while(gets(a))
{
int i,j,k;
struct node e;
int len=strlen(a);
for(i=0,j=0;i<=len-1;i++)
{
if(a[i]==' ')continue;
else if(a[i]=='x')
{
e.f[j/3][j%3]=0;
e.x=j/3;
e.y=j%3;
}
else e.f[j/3][j%3]=a[i]-'0';
j++;
}
for(i=0,k=0;i<=8;i++)
{
if(e.f[i/3][i%3]==0) continue;
for(j=0;j<=i-1;j++)
{
if(e.f[j/3][j%3]==0) continue;
if(e.f[j/3][j%3]>e.f[i/3][i%3])k++;
}
}
if(k&1) printf("unsolvable\n");//如果k为奇数
else A_star(e);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: