首页 > 试题广场 >

八数码

[编程题]八数码
  • 热度指数:180 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 128M,其他语言256M
  • 算法知识视频讲解

八数码问题,就是在一个含有1-8和x的3*3方格中,每次可以将x与其相邻位置的数字交换。使得最后变成

1 2 3
4 5 6
7 8 x

你要做的就是实现八数码的解决方案,并要求交换次数最少。


输入描述:
输入一个3*3的矩阵,包含1-8和x。


输出描述:
输出需要移动的步数
如果不可能实现,输出-1。
示例1

输入

2  3  4  
1  5  x  
7  6  8

输出

19
#include<cstdio>
#include<cstring>
#include<map>
#include<queue>
#define maxn 3
using namespace std;

int aim = 0;
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};

struct Node
{
    int x, y;
    int step = 0;
    // int status;
    char status[maxn][maxn];
};
Node s;

bool judge(const Node &a)
{
    if (a.x<0 || a.x>2 || a.y<0 || a.y>2)
        return false;
    return true;
}

int matrix2int(char status[maxn][maxn])
{    //得到每一种状态的标识
    int ans = 0;
    for (int i = 0; i < 3; i++)
        for (int j = 0; j < 3; j++)
            ans = ans*10+status[i][j]-'0';
    return ans;
}

void copyM(char a[maxn][maxn], char b[maxn][maxn])
{
    for(int i=0; i<3; i++)
        for(int j=0; j<3; j++)
            b[i][j] = a[i][j];
}

int bfs()
{
    queue<Node> q;
    map<int, int> hashMp;
    // Node next;
    q.push(s);
    int key = matrix2int(s.status);
    if (key==aim)
        return 1;
    ++hashMp[key];
    while (!q.empty())
    {
        s = q.front();
        q.pop();
        for (int i = 0; i < 4; i++)
        {
            Node next = s;
            next.x = s.x+dx[i];
            next.y = s.y+dy[i];
            next.step = s.step+1;
            if (judge(next))
            {
                // copyM(s.status, next.status);
                swap(next.status[next.x][next.y], next.status[s.x][s.y]);
                int key = matrix2int(next.status);
                if (key == aim)
                    return next.step;
                if (hashMp[key]==0)
                {
                    q.push(next);
                    hashMp[key]++;
                }
            }
        }
    }
    return -1;
}

int main()
{
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            scanf("%c", &s.status[i][j]);
            getchar();  //吃空格和回车
            if (s.status[i][j]=='x')    //把x换成0字符
            {
                s.x = i, s.y = j;
                s.status[i][j]='0';
            }
               
        }
    }
    aim=123456780;

    printf("%d\n", bfs());
    return 0;
}

编辑于 2021-02-01 16:37:57 回复(0)

问题信息

上传者:小小
难度:
1条回答 1516浏览

热门推荐

通过挑战的用户