您的位置:首页 > 其它

hdu 1043 #八数码#全排列逆序对的哈希+BFS

2012-07-25 12:21 183 查看
之前这题超时的,因为每次都BFS了。

当时实在是蠢了,其实只要以终态为起点一次BFS就记录好所有路径了

#include <stdio.h>
#include <queue>
#include <iostream>
#include <string.h>
using namespace std;
#define N 1000000
struct node
{
int x,y;
char mat[3][3];
}p,pt;

char dir
;
int nxt
;
int move[][2] = {0,1,1,0,0,-1,-1,0};
char mo[5] = "lurd";
int fac[] = {1,1,2,6,24,120,720,5040,40320};

bool inner(int x,int y)
{
return x >=0 && x < 3 && y >=0 && y < 3;
}
int get_hash(node p)
{
int i,j,k,ans = 0,d;
char temp[10];
for(i = 0; i < 3; ++i)
for(j = 0; j < 3; ++j)
{
temp[i*3+j] = p.mat[i][j];
d = 0;
for(k = 0; k < i * 3 + j; ++k)
if(temp[k] > p.mat[i][j])
++d;
ans += fac[i*3+j] * d;
}
return ans;
}
void bfs()
{
for(int i = 0; i < 3; ++i)
for(int j = 0; j < 3; ++j)
p.mat[i][j] = '1' +  i * 3 + j;
p.mat[2][2] = '0';
p.x = p.y = 2;

memset(nxt,-1,sizeof(nxt));
queue<node> que;
que.push(p);
int hh,h = get_hash(p);
nxt[h] = -2;
dir[h] = '\n';
while(!que.empty())
{
p = que.front();
que.pop();
h = get_hash(p);
for(int i = 0; i < 4; ++i)
{
pt = p;
pt.x += move[i][0];
pt.y += move[i][1];
if(inner(pt.x,pt.y))
{
swap(pt.mat[p.x][p.y],pt.mat[pt.x][pt.y]);
hh = get_hash(pt);
if(nxt[hh] == -1)
{
nxt[hh] = h;
dir[hh] = mo[i];
que.push(pt);
}
}
}
}
}
int main()
{
bfs();
int i,j;
while(cin >> p.mat[0][0])
{
cin >> p.mat[0][1] >> p.mat[0][2];
for(i = 1; i < 3; ++i)
for(j = 0; j < 3; ++j)
cin >>p.mat[i][j];
for(i = 0; i < 3; ++i)
for(j = 0; j < 3; ++j)
if(p.mat[i][j] == 'x')
p.mat[i][j] = '0';

int h = get_hash(p);
if(nxt[h] == -1)
printf("unsolvable\n");
else
{
for(; nxt[h] != -2; h = nxt[h])
printf("%c",dir[h]);
printf("\n");
}
}
return 0;
}


#include<iostream>
#include<queue>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;

char ms[6]="rdul";
int vis[400000],id;
int pre[600000];
char path[600000];
int fac[]={1,1,2,6,24,120,720,5040,40320};

struct node
{
int pos,id;
int s[9];
}p,p2;
int hash(int *str)
{
int i,j,cnt,res=0,jac=1;
for(i=1;i<9;++i)
{
cnt=0;
for(j=0;j<i;++j)
if(str[j]>str[i])
++cnt;
res+=cnt*fac[i];
}
return res;
}
void output(int s)
{
char str[400000];
int k=0;
while(s)
{
str[k++]=path[s];
s=pre[s];
}
for(k--;k>=0;--k)
printf("%c",str[k]);
printf("\n");
}
//int final=hash("123456789");//终态的哈希值为0
int bfs()
{
queue<node> que;
int h;

h=hash(p.s);
if(!h)
{
printf("\n");
return 1;
}

memset(vis,0,sizeof(vis));
p.id=0;
que.push(p);
vis[h]=1;
id=0;
while(!que.empty())
{
p=que.front();
que.pop();

if(p.pos%3!=2)
{
p2=p;
swap(p2.s[p.pos],p2.s[p.pos+1]);
h=hash(p2.s);
if(!vis[h])
{
vis[h]=1;
p2.id=++id;
pre[id]=p.id;
path[id]=ms[0];
if(!h)
{
output(id);
return 1;
}
p2.pos=p.pos+1;
que.push(p2);
}
}
if(p.pos%3)
{
p2=p;
swap(p2.s[p.pos],p2.s[p.pos-1]);
h=hash(p2.s);

if(!vis[h])
{
vis[h]=1;
p2.id=++id;
pre[id]=p.id;
path[id]=ms[3];
if(!h)
{
output(id);
return 1;
}
p2.pos=p.pos-1;
que.push(p2);
}
}
if(p.pos>2)
{
p2=p;
swap(p2.s[p.pos],p2.s[p.pos-3]);
h=hash(p2.s);

if(!vis[h])
{
vis[h]=1;
p2.id=++id;
pre[id]=p.id;
path[id]=ms[2];
if(!h)
{
output(id);
return 1;
}
p2.pos=p.pos-3;
que.push(p2);
}
}
if(p.pos<6)
{
p2=p;
swap(p2.s[p.pos],p2.s[p.pos+3]);
h=hash(p2.s);

if(!vis[h])
{
vis[h]=1;
p2.id=++id;
pre[id]=p.id;
path[id]=ms[1];
if(!h)
{
output(id);
return 1;
}
p2.pos=p.pos+3;
que.push(p2);
}
}
}
return 0;
}
int main()
{
int i,j=0;
char e[3];

while(scanf("%s",e)==1)
{
if(e[0]=='x')
{
p.s[0]=9;
p.pos=0;
}
else
p.s[0]=e[0]-'0';
for(i=1;i<9;++i)
{
scanf("%s",e);
if(e[0]=='x')
{
p.s[i]=9;
p.pos=i;
}
else
p.s[i]=e[0]-'0';
}
if(!bfs())
printf("unsolvable\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: