简单的八数码问题(BFS)

问题 A: 八数码

时间限制: 1 Sec   内存限制: 256 MB
提交: 9   解决: 7
[ 提交][ 状态][ 讨论版]

题目描述

在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。

输入

输入初试状态,一行九个数字,空格用0表示

输出

只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊无法到达目标状态数据)。

样例输入

283104765

样例输出

4

提示



//
//  main.cpp
//  问题 A: 八数码
//
//  Created by wenhan on 2017/7/28.
//  Copyright © 2017年 wenhan. All rights reserved.
//

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#include <vector>
#include <map>
#include <algorithm>
int s=0;
struct me{
    int c[4][4];
    int cur;
    int x,y;
}me;
int v[4][4]={{0,0,0,0},{0,1,2,3},{0,8,0,4},{0,7,6,5}};
int t[4][4];
using namespace std;
bool panduan(struct me a)
{
    for(int i=1;i<=3;i++)
        for(int j=1;j<=3;j++)
            if(a.c[i][j]!=v[i][j])
                return false;
    return true;
}
void bfs()
{
    if(panduan(me))
        return;
    queue<struct me>my;
    map<long long,int>mx;
    my.push(me);
    while (!my.empty()) {
        struct me x=my.front();
        my.pop();
        int ss=0;
        for(int i=1;i<=3;i++)
            for(int j=1;j<=3;j++)
                ss=ss*10+x.c[i][j];
        if(mx.count(ss))
            continue;
        if(panduan(x))
        {
            me.cur=x.cur;
            return;
        }
        mx[ss]=1;
        for(int i=1;i<=3;i++)
            for(int j=1;j<=3;j++)
                if(x.c[i][j]==0)
                {
                    x.x=i;x.y=j;
                    break;
                }
        //printf("%d\n",x.cur);
        //接下来是4个方向,我人傻,大神请勿喷
        if(x.x+1<=3)
        {
            struct me y;
            y=x;
            swap(y.c[y.x][y.y], y.c[y.x+1][y.y]);
            y.cur++;
            my.push(y);
        }
        if(x.x-1>=1)
        {
            struct me y;
            y=x;
            swap(y.c[y.x][y.y], y.c[y.x-1][y.y]);
            y.cur++;
            my.push(y);
        }
        if(x.y+1<=3)
        {
            struct me y;
            y=x;
            swap(y.c[y.x][y.y], y.c[y.x][y.y+1]);
            y.cur++;
            my.push(y);
        }
        if(x.y-1>=1)
        {
            struct me y;
            y=x;
            swap(y.c[y.x][y.y], y.c[y.x][y.y-1]);
            y.cur++;
            my.push(y);
        }
    }
    
}
int main() {
    char a[11];
    scanf("%s",a);
    for(int i=1;i<=3;i++)
        for (int j=1; j<=3; j++) {
            me.c[i][j]=a[s++]-'0';
        }
    me.cur=0;
    s=0;
    bfs();
    printf("%d\n",me.cur);
    // insert code here...
    //std::cout << "Hello, World!\n";
    return 0;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值