第十九章 ALDS1_13_B:8 Puzzle 九宫格拼图

问题链接

ALDS1_13_B:8 Puzzle

问题内容

求当前9宫格如何移动成目标的9宫格。

思路

同样使用回溯的方法去做。

代码

#include<iostream>   
#include<cstdio>  
#include<algorithm>
#include<queue>
#include<map>
#include<string>
using namespace std;
const int row = 3;
const int maxx = 9;

struct Puzzle {
    int f[maxx];
    int space;
    string path;
    bool operator < (const Puzzle &p) const {
        for (int i = 0; i < maxx; i++) {
            if (f[i] != p.f[i])
                return f[i] > p.f[i];
        }
        return false;
    }
};

const int dx[4] = { -1, 0, 1, 0 };
const int dy[4] = { 0, -1, 0 ,1 };
const char dir[4] = { 'u','l','d','r' };

bool isTarget(Puzzle p) {
    for (int i = 0; i < maxx; i++)
        if (p.f[i] != (i + 1))
            return false;
    return true;
}


string bfs(Puzzle s) {
    queue<Puzzle> Q;
    map<Puzzle, bool> V;
    Puzzle u, v;
    s.path = "";
    Q.push(s);
    V[s] = true;

    while (!Q.empty()) {
        u = Q.front(); Q.pop();
        if (isTarget(u))
            return u.path;
        int sx = u.space / row;
        int sy = u.space % row;
        for (int r = 0; r < 4; r++) {
            int tx = sx + dx[r];
            int ty = sy + dy[r];

            if (tx < 0 || ty < 0 || tx >= row || ty >= row)
                continue;
            v = u;
            swap(v.f[u.space], v.f[tx * row + ty]);
            v.space = tx * row + ty;
            if (!V[v]) {
                V[v] = true;
                v.path += dir[r];
                Q.push(v);
            }
        }
    }
    return "unsolveable";
}
int main()
{
    Puzzle in;
    for (int i = 0; i < maxx; i++) {
        cin >> in.f[i];
        if (in.f[i] == 0) {
            in.f[i] = maxx;
            in.space = i;
        }
    }
    string ans = bfs(in);
    printf("%d\n", ans.size());
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值