曼哈顿距离作为估价函数。
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1043
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <string.h>
#include <stdlib.h>
#include <string>
#include <vector>
#define maxn 400000
using namespace std;
struct Node{
int a[10];
int x,y;
int g,h;
int Hash;
//bool operator < (const Node n1)const{
// return h!=n1.h?h>n1.h:g>n1.g;
//}
friend bool operator < (const Node & a1,const Node & a2){
if(a1.h==a2.h)
return a1.g < a2.g;
else
return a1.h > a2.h;
}
bool check(){
if(x>=0&&x<3&&y>=0&&y<3)
return true;
else
return false;
}
}s,u,v,tt;
int Hct[10] ={1,1,2,6,24,120,720,5040,40320,362880};
int destination ;
char vis[maxn];
int pre[maxn];
char d[5] = "rldu";
int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};
void Dedug(Node tmp){
int i;
for(i=0;i<9;i++){
printf("%d",tmp.a[i]);
}
puts("");
printf("x : %d y : %d\n",tmp.x,tmp.y);
printf("g : %d h : %d\n",tmp.g,tmp.h);
printf("Hash : %d\n",tmp.Hash);
}
int ct(int * a){
int i,j,con,zans = 0;
for(i=0;i<8;i++){
con = 0;
for(j=i+1;j<9;j++){
if(a[j]<a[i])con++;
}
zans += con * Hct[8-i];
}
return zans;
}
/*
int ct(int * a){
int k=0,res=0;
for(int i=0;i<9;i++){
int k=0;
for(int j=0;j<i;j++)
if(a[j]>a[i])
k++;
res+=Hct[i]*k;
}
return res;
}
*/
bool i_sok(int * a){
int con=0,i,j;
for(i=0;i<8;i++){
for(j=i+1;j<9;j++){
if(a[i]&&a[j]&&a[j]<a[i]){
con++;
}
}
}
return !(con&1);
}
int get_h(int * a){
int ans=0;
int i,j1,k1,j2,k2;
for(i=0;i<9;i++){
if(a[i]){
j1 = (a[i]-1) / 3;
k1 = (a[i]-1) % 3;
j2 = i / 3;
k2 = i % 3;
ans += abs(j1-j2)+abs(k1-k2);
}
}
return ans;
}
void Astar(){
int i;
priority_queue<Node>q;
q.push(s);
while(!q.empty()){
u = q.top();
q.pop();
for(i=0;i<4;i++){
v = u;
int temp1 = v.x * 3 + v.y;
v.x += dx[i];
v.y += dy[i];
if(v.check()){
int temp2= v.x * 3 + v.y;
v.a[temp1] = v.a[temp2];
v.a[temp2] = 0;
v.Hash = ct(v.a);
if(vis[v.Hash]==-1){
vis[v.Hash] = d[i];
pre[v.Hash] = u.Hash;
v.h = get_h(v.a);
q.push(v);
}
}
if(v.Hash==destination)
return ;
}
}
}
void print(){
string ans = "";
int i,nxt = destination;
while(pre[nxt]!=-1){
ans+=vis[nxt];
nxt = pre[nxt];
}
for(i=ans.length()-1;i>=0;i--){
cout<<ans[i];
}
cout<<endl;
}
int main(void){
//freopen("a.in","r",stdin);
char tempa[105];
int i,k;
int Tmp[10] = {1,2,3,4,5,6,7,8,0};
destination = ct(Tmp);
while(gets(tempa)){
memset(vis,-1,sizeof(vis));
memset(pre,-1,sizeof(pre));
k = 0;
for(i=0;i<strlen(tempa);i++){
if(tempa[i]>'0'&&tempa[i]<'9')
s.a[k++] = tempa[i] - '0';
if(tempa[i]=='x'){
s.a[k++] = 0;
s.x = (k - 1)/3;
s.y = (k - 1)%3;
}
}
if(!i_sok(s.a)){
puts("unsolvable");continue;
}
s.Hash = ct(s.a);
vis[s.Hash] = -2;
if(s.Hash==destination){
puts("");continue;
}
s.h = get_h(s.a);
s.g = 0;
//Dedug(s);
Astar();
print();
}
}