###### HDU 1043 Eight poj 1077 （八数码 启发式搜索）

poj1077
hdu1043

A*是bfs的一种优化，使用函数F做为每个节点的访问的优先级

hdu的需要先判断是否有解，否则会tle，加上后跑了1000+ms
poj的不用判断，也可以ac，跑了40+ms

//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
#define cl(a,b) memset(a,b,sizeof(a))
#define fastIO ios::sync_with_stdio(false);cin.tie(0);
#define LL long long
#define pb push_back
#define gcd __gcd

#define For(i,j,k) for(int i=(j);i<=k;i++)
#define lowbit(i) (i&(-i))
#define _(x) printf("%d\n",x)

typedef vector<LL> vec;
typedef pair<int,int> PI;
const double EPS = 1e-8;
const int maxn = 4e5;
const int inf  = 1 << 28;
int fac[10];
void init(){
fac[0] = 1;
for(int i=1;i<=9;i++)fac[i]=fac[i-1]*i;
}
int contor(int a[]){
int ans = 0, n = 9;
for(int i=0;i<n;i++){
int tp = 0;
for(int j=i+1;j<n;j++)if(a[j]<a[i])tp++;
ans+=tp*fac[n-1-i];
}
return ans;
}
int getH(int a[]){
int ret = 0;
for(int i=0;i<9;i++){
int x = i / 3;
int y = i % 3;
int xx = (a[i] - 1) / 3;
int yy = (a[i] - 1) % 3;
ret += abs(x-xx)+abs(y-yy);
}
return ret;
}

int dir[2][4]={0,0,-1,1,-1,1,0,0};
char *dirc = "lrud";
int vis[maxn];//closed list
struct node{
int a[10];
int x,y;
int F,G,H;
int id;
bool isok(){
if(x >= 0 && x <= 2 && y >= 0 && y <= 2)return true;
return false;
}
bool operator<(const node&rhs) const{
return F > rhs.F || F == rhs.F && G > rhs.G;
}
}start,last,now;

struct path{
int id,dir;
}fa[maxn];
int bfs(){
priority_queue<node> q;
cl(vis,false);

q.push(start);

while(!q.empty()){
last = q.top();q.pop();

for(int i=0;i<4;i++){
now = last;
now.x += dir[0][i];
now.y += dir[1][i];
if(!now.isok())continue;
swap(now.a[last.x*3+last.y], now.a[now.x*3+now.y]);
now.id = contor(now.a);
if(vis[now.id])continue;
now.G = last.G + 1;
now.H = getH(now.a);
now.F = now.G + now.H;
fa[now.id] = (path){last.id,i};

q.push(now);
if(now.id == 0)return now.G;
}
vis[last.id] = true;
}
return -1;
}

bool isok(int a[]){
int sum = 0;
for(int i=0;i<9;i++){
for(int j=i+1;j<9;j++){
if(a[i]==9||a[j]==9)continue;
if(a[i]>a[j])sum++;
}
}
return sum%2 == 0;
}

char str[3];
vector<char> v;
int main(){
init();
while(~scanf("%s",str)){
start.a[0] = str[0] == 'x' ? 9 : str[0] - '0';
for(int i=1;i<=8;i++){
scanf("%s",str);
start.a[i] = str[0] == 'x' ? 9 : str[0] - '0';
}
//for(int i=0;i<9;i++)printf("%d ",start.a[i]);

for(int i=0;i<9;i++)if(start.a[i]==9){start.x = i/3;start.y = i%3;break;}
start.G = 0;
start.H = getH(start.a);
start.F = start.G + start.H;
start.id = contor(start.a);

if(start.id == 0){
puts("");continue;
}
if(!isok(start.a)){
puts("unsolvable");continue;
}

cl(fa,-1);

int ans = bfs();

if(ans == -1){
puts("unsolvable");
}
else {
v.clear();
path t = fa[0];
while(t.id!=-1){
//printf("t = %d %d\n",t.id,t.dir);
//putchar(dirc[t.dir]);
v.pb(dirc[t.dir]);
t = fa[t.id];
}
for(int i=v.size()-1;i>=0;i--){
printf("%c",v[i]);
}
printf("\n");
}

}
return 0;
}


#### hdu 1043 Eight(八数码问题 高级搜索： A* 搜索)

2017-01-10 17:42:52

#### hdu 1043/poj 1077 Eight （八数码 经典搜索题 bfs + 康托展开）

2016-10-06 20:34:27

#### 【HDU 1043】Eight（A*启发式搜索算法）

2016-08-04 15:52:59

#### hdu1043Eight (经典的八数码)（康托展开+BFS）

2014-05-29 22:23:06

#### HDU 1043 Eight 八数码问题 A*搜索 启发式算法

2016-07-31 21:54:47

#### hdu 1034 & poj 1077 Eight 传说中的八数码问题。真是一道神题，A*算法+康托展开

2015-02-15 00:04:49

#### POJ 1077 八数码 三种解法

2016-05-31 13:41:40

#### POJ1077(经典的八数码问题)

2012-08-05 11:00:49

#### hdu1043 Eight（A*/双向BFS/单项BFS打表+康托展开）

2015-10-11 17:42:22

#### hdu 3567 Eight II 八数码 双向BFS

2014-07-27 14:04:44

## 不良信息举报

HDU 1043 Eight poj 1077 （八数码 启发式搜索）