POJ 1077 Eight A*

/*终于用A*做出了这道经典八数码*/ #include<stdio.h> #include<cstring> #include<cmath> #include<string> #include<queue> using namespace std; struct point{ char board[10]; int space; }; int f[400000],d[400000]; int colour[400000],parent[400000],moves[400000],path[400000]; int fac[10]={ 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880 }; int xx[4]={1,-1,0,0}; int yy[4]={0,0,1,-1}; struct cmp{ bool operator()(const int u,const int v){ return f[u]>f[v]; } }; int calhash(char * tmp){ int i,j; int temp=0,sum=0; for(i=0;i<9;i++){ temp=0; for(j=i+1;j<9;j++){ if(tmp[i]>tmp[j]) temp++; } sum+=temp*fac[9-i-1]; } return sum; } int h(struct point & temp){ int i,j,k,sum=0; for(i=0;i<3;i++) for(j=0;j<3;j++){ k=i*3+j; if(temp.board[k]!='9'){ sum+=abs(i-(temp.board[k]-'1')/3)+abs(j-(temp.board[k]-'1')%3); } } return sum; } void get_node(int per,struct point & cur){ int i,j=0,k,temp,flag[10]; memset(flag,0,sizeof(flag)); for(i=8;i>=0;i--){ temp=0; cur.board[j]=per/fac[i]; for(k=1;k<10;k++){ if(temp==cur.board[j] && flag[k]==0) break; if(flag[k]==0) temp++; } flag[k]=1; cur.board[j]=k+'0'; if(cur.board[j]=='9'){ cur.space=j; } j++; per%=fac[i]; } } int Astar(struct point & sta){ int u,v,k,x,y,i,xxx,yyy,z; priority_queue<int,vector<int>,cmp> que; struct point cur,temp; moves[0]=-1; u=calhash(sta.board); f[u]=h(sta); d[u]=0; que.push(u); colour[u]=1; parent[u]=-1; while(!que.empty()){ int tem; tem=que.top(); if(tem==0) return 1; que.pop(); get_node(tem,cur); k=cur.space; x=k/3; y=k%3; for(i=0;i<4;i++){ xxx=x+xx[i]; yyy=y+yy[i]; if(xxx<0 || xxx>2 || yyy<0 || yyy>2) continue; temp.space=3*xxx+yyy; temp.board[temp.space]='9'; temp.board[cur.space]=cur.board[temp.space]; for(z=0;z<9;z++){ if(z!= temp.space && z!=cur.space) temp.board[z]=cur.board[z]; } v=calhash(temp.board); if(colour[v]==1 && (d[tem]+1<d[v])){ moves[v]=i; parent[v]=tem; f[v]=f[v]-d[v]+d[tem]+1; d[v]=d[tem]+1; } else if(colour[v]==2 && (d[tem]+1<d[v])){ moves[v]=i; parent[v]=tem; f[v]=f[v]-d[v]+d[tem]+1; d[v]=d[tem]+1; colour[v]=1; que.push(v); } else if(colour[v]==0){ moves[v]=i; parent[v]=tem; d[v]=d[tem]+1; f[v]=d[v]+h(temp); que.push(v); colour[v]=1; } } colour[tem]=2; } return 0; } void printpath(){ int i,t; if(moves[0]==-1){ printf("\n"); return; } t=0; i=0; while(parent[t]!=-1){ path[i++]=moves[t]; t=parent[t]; } --i; for(;i>=0;i--){ if(path[i]==0) printf("d"); else if(path[i]==1) printf("u"); else if(path[i]==2) printf("r"); else printf("l"); } printf("\n"); } int main(){ int i,j,k; char input[30]; gets(input); i=0;j=0; struct point sta; while(input[i]!='\0'){ if(input[i]==' ') ; else if(input[i]=='x'){ sta.board[j++]='9'; sta.space=j-1; } else sta.board[j++]=input[i]; i++; } if(Astar(sta)){ printpath(); } else printf("unsolvable\n"); }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值