noj 算法 八数码问题

描述
在九宫格里放在1到8共8个数字还有一个是空格,与空格相邻的数字可以移动到空格的位置,问给定的状态最少需要几步能到达目标状态(用0表示空格):
1 2 3
4 5 6
7 8 0
 
输入
输入一个给定的状态。
 
输出
输出到达目标状态的最小步数。不能到达时输出-1。
 
输入样例
1 2 3
4 0 6
7 5 8
 
输出样例
2
 
代码:
#include <iostream>
#include <stdio.h>
#include<queue>
#include<map>

using namespace std;
int a[3][3];
queue<int>q;
int dir[4][2]={-1,0,0,1,1,0,0,-1};
int r,c;
map<int,int>visited;
map<int,int>step;

int canmove(int u,int d)
{
    for(int i=2;i>=0;i--){
        for(int j=2;j>=0;j--){
            a[i][j]=u%10;
            u/=10;
            if(a[i][j]==0){
                r=i;
                c=j;
            }
        }
    }
    if((d==0&&r==0)||(d==1&&c==2)||(d==2&&r==2)||(d==3&&c==0))
        return 0;
    return 1;
}

int moveto(int u,int d)
{
    int t=0;
    int nr=r+dir[d][0];
    int nc=c+dir[d][1];
    a[r][c]=a[nr][nc];
    a[nr][nc]=0;
    for(int i=0;i<3;i++)
        for(int j=0;j<=2;j++)
    {
        t=t*10+a[i][j];
    }
    return t;
}

int bfs(int n)
{
    q.push(n);
    visited[n]=1;
    step[n]=0;
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        if(u==123456780)
            return step[u];
        for(int i=0;i<4;i++)
        {
            if(canmove(u,i))
            {
                int v=moveto(u,i);
                if(!visited[v])
                {
                    visited[v]=1;
                    step[v]=step[u]+1;
                    q.push(v);
                }
            }
        }
    }
    return -1;
}

int main()
{
    int i,j,n=0;
    for(i=0;i<3;i++){
        for(j=0;j<3;j++){
            cin>>a[i][j];
            n=n*10+a[i][j];
        }
    }
    int sum=bfs(n);
    cout<<sum<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/y1040511302/p/9803915.html