您的位置:首页 > 其它

洛谷P1379 八数码难题

2015-06-13 21:42 274 查看
题目:http://www.luogu.org/problem/show?pid=1379#

分析:此题有多种做法,这里介绍一种(隐式图+hash)的办法

总结:如果不确定hash写错,可以用set代替来检验,字符串最好从0开始用,否则莫名错误

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
int dx[5]={0,-1,0,1,0},dy[5]={0,0,1,0,-1},first[1333335],next[362885],hashdata[362885][10],len;
char start[10],goal[10]={'1','2','3','8','0','4','7','6','5','\0'};
struct node{
char s[10];
int dist;
};
queue <node> q;
int hash(char *s)
{
int sum=0;
for(int i=0;i<9;i++)
sum=sum*10+s[i]-'0';
return sum%1333331;
}
bool try_insert(char *s)
{
int h=hash(s),p=first[h];
while(p){
if(!memcmp(hashdata[p],s,sizeof(s))) return false;
p=next[p];
}
memcpy(hashdata[++len],s,sizeof(s)+1);
next[len]=first[h];
first[h]=len;
return true;
}
int bfs()
{
int i,white,x,y,newx,newy,change;
node a,b;
memcpy(a.s,start,sizeof(start)+1);
a.dist=0;
q.push(a);
try_insert(a.s);
while(!q.empty())
{
a=q.front();q.pop();
if(!memcmp(a.s,goal,sizeof(goal))) return a.dist;
for(i=0;i<9;i++)
if(a.s[i]=='0'){
white=i;
break;
}
x=white/3;
y=white%3;
for(i=1;i<=4;i++)
{
newx=x+dx[i];newy=y+dy[i];change=newx*3+newy;
if(newx>=0&&newx<3&&newy>=0&&newy<3)
{
memcpy(&b,&a,sizeof(a));
b.s[change]='0';b.s[white]=a.s[change];
b.dist=a.dist+1;
if(try_insert(b.s)) q.push(b);
}
}
}
return 0;
}
int main()
{
scanf("%s",start);
printf("%d\n",bfs());
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: