luogu P1379 八数码难题(A*算法入门详细讲解)

 

 代码实现细节

 

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int N=10;
const int dx[]={0,0,1,-1};
const int dy[]={1,-1,0,0};
int flag,now[N],goal[N];
int dis[N][N],a[N][N],mp[N][N];
inline int calcx(int x){return (x-1)/3+1;}
inline int calcy(int x){return x%3?x%3:3;}
inline int abs(int x){return x>0?x:-x;}
inline int h(){int t=0;for(int i=1;i<=9;i++) t+=dis[now[i]][goal[i]];return t;}
inline int check(){for(int i=0;i<9;i++) if(now[i]!=goal[i]) return 0;return 1;}
void dfs(int depth,int x,int y,int lim){
    if(depth+h()>lim) return ;
    if(check()){flag=1;return ;}
    for(int i=0,nx,ny;i<4;i++){
        nx=x+dx[i];
        ny=y+dy[i];
        if(flag) return ;
        if(nx>0&&nx<=3&&ny>0&&ny<=3){
            swap(a[x][y],a[nx][ny]);swap(now[a[x][y]],now[a[nx][ny]]);
            dfs(depth+1,nx,ny,lim);
            swap(a[x][y],a[nx][ny]);swap(now[a[x][y]],now[a[nx][ny]]);
        }
    }
}
void pre(){
    for(int i=1;i<=9;i++)
        for(int j=i+1;j<=9;j++)
            dis[i][j]=dis[j][i]=calcx(j)-calcx(i)+abs(calcy(j)-calcy(i));
}
int main(){
    pre();
    goal[0]=5;goal[1]=1;goal[2]=2;goal[3]=3;goal[4]=6;goal[5]=9;goal[6]=8;goal[7]=7;goal[8]=4;
    int sx,sy;
    for(int i=1,x,y,z;i<=9;i++){
        scanf("%1d",&z);
        x=calcx(i);y=calcy(i);
        mp[x][y]=z;now[z]=i;
        if(!z) sx=x,sy=y;
    }
    for(int i=0;;i++){
        memcpy(a,mp,sizeof mp);
        dfs(0,sx,sy,i);
        if(flag){printf("%d\n",i);break;}
    }
    return 0;
}

 

posted @ 2017-04-12 15:18  神犇(shenben)  阅读(3492)  评论(0编辑  收藏  举报