NOJ1326——算法实验三——推箱子

推箱子

描述

绝大多数人都玩过推箱子的游戏,控制一个人将箱子推动到目标位置即获得胜利。现请你编写一个程序,判断将箱子推到目标位置至少需要多少步。

输入

推箱子的平面区域为固定大小(10*10),使用10行10列输入推箱子的初始局面。其中,0代表空格,1代表墙,2代表箱子,3代表目标位置,4代表人。
注:游戏中只有一个箱子,一个目标位置,一个人。

输出

输出将箱子推到目标位置的最小步数;若箱子不可能被推到目标位置,输出-1。

输入样例

0000000000
0000000300
0100000000
0100000000
0101111100
0000010000
0000010000
0020010040
0000010000
0000010000

输出样例

34

源代码

#include <iostream>
#include <queue>

using namespace std;

int maze[10][10];
int vis[10][10][10][10];
int step[10][10][10][10];
struct Node{
    int px, py;
    int bx, by;
};
int tx, ty;
int walk[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
void input()
{
    int i, j;
    char c;
    for (i = 0; i < 10;i++)
    {
        for (j = 0; j < 10; j++)
        {
            cin >> c;
            maze[i][j] = c - '0';
        }
    }
}
int bfs()
{
    int i, j;
    queue<Node> q;
    Node now, next;
    for (i = 0; i < 10;i++)
    {
        for (j = 0; j < 10;j++)
        {
            if(maze[i][j] == 4)
            {
                now.px = i;
                now.py = j;
                maze[i][j] = 0;
            }
            if(maze[i][j] == 3)
            {
                tx = i;
                ty = j;
                maze[i][j] = 0;
            }
            if(maze[i][j] == 2)
            {
                now.bx = i;
                now.by = j;
                maze[i][j] = 0;
            }
        }
    }
    vis[now.px][now.py][now.bx][now.by] = 1;
    q.push(now);
    while(!q.empty())
    {
        now = q.front();
        q.pop();
        for (i = 0; i < 4;i++)
        {
            next.px = now.px + walk[i][0];
            next.py = now.py + walk[i][1];
            next.bx = now.bx;
            next.by = now.by;
            if(next.px < 0 || next.px >= 10 || next.py < 0 || next.py >= 10)//越界
            {
                continue;
            }
            else if(vis[next.px][next.py][next.bx][next.by] == 1)//重复
            {
                continue;
            }
            else if(maze[next.px][next.py] == 1)//撞墙
            {
                continue;
            }
            else if(maze[next.px][next.py] == 0 && (next.px != next.bx || next.py != next.by) )//空格
            {
                vis[next.px][next.py][next.bx][next.by] = 1;
                step[next.px][next.py][next.bx][next.by] = step[now.px][now.py][now.bx][now.by] + 1;
                q.push(next);
                continue;
            }
            else//箱子
            {
                next.bx += walk[i][0];
                next.by += walk[i][1];
                if(next.bx < 0 || next.bx >= 10 || next.by < 0 || next.by >= 10)//箱子越界
                {
                    continue;
                }
                if(vis[next.px][next.py][next.bx][next.by] == 1)//重复
                {
                    continue;
                }
                if(maze[next.bx][next.by] == 1)//撞墙
                {
                    continue;
                }
                if(maze[next.bx][next.by] == 0)
                {
                    if(next.bx == tx && next.by == ty)
                    {
                        return step[now.px][now.py][now.bx][now.by] + 1;
                    }
                    vis[next.px][next.py][next.bx][next.by] = 1;
                    step[next.px][next.py][next.bx][next.by] = step[now.px][now.py][now.bx][now.by] + 1;
                    q.push(next);
                }
            }
        }
    }
    return -1;
}
int main()
{
    input();
    cout << bfs() << endl;
}

思路

还是迷宫的老套路,不过是多了一个箱子:

  1. 扩展结点非法(撞墙,重复,越界)则continue。
  2. 扩展结点为空格,就入队并记录。
  3. 扩展结点为箱子,判断箱子的扩展结点(必须与之前人的扩展结点对应),箱子的扩展结点合法,入队,并记录。
  4. 箱子到达目标点返回当前步数加1。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
´问题描述: 码头仓库是划分为n×m个格子的矩形阵列。有公共边的格子是相邻格子。当前仓库中 有的格子是空闲的;有的格子则已经堆放了沉重的货物。由于堆放的货物很重,单凭仓库管 理员的力量是无法移动的。仓库管理员有一项任务,要将一个小箱子推到指定的格子上去。 管理员可以在仓库中移动,但不能跨过已经堆放了货物的格子。管理员站在与箱子相对的空 闲格子上时,可以做一次推动,把箱子推到另一相邻的空闲格子。推箱时只能向管理员的对 面方向推。由于要推动的箱子很重,仓库管理员想尽量减少推箱子的次数。 ´编程任务: 对于给定的仓库布局,以及仓库管理员在仓库中的位置和箱子的开始位置和目标位置, 设计一个解推箱子问题的分支限界法, 计算出仓库管理员将箱子从开始位置推到目标位置所 需的最少推动次数。 ´数据输入: 由文件input.txt提供输入数据。输入文件第 1 行有 2个正整数 n和 m(1<=n,m<=100) , 表示仓库是n×m个格子的矩形阵列。接下来有 n行,每行有 m个字符,表示格子的状态。 S 表示格子上放了不可移动的沉重货物; w 表示格子空闲; M 表示仓库管理员的初始位置; P 表示箱子的初始位置; K 表示箱子的目标位置。 ´结果输出: 将计算出的最少推动次数输出到文件 output.txt。如果仓库管理员无法将箱子从开始位 置推到目标位置则输出“No solution!” 。 输入文件示例 输出文件示例 input.txt output.txt
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Alfred young

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值