【Ybtoj 第5章 例题3】立体推箱子【广搜】

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


解题思路

首先这个是广搜。
可以预处理出刚开始的箱子状态和终点。
那么 1 × 2 1×2 1×2 的情况怎么记录呢?
我们可以记录第一个格子,然后直接把第二个格子判断状态即可。
然后对于箱子的移动很麻烦,我们要用 d x , d y dx,dy dx,dy表示移动方向, d t dt dt表示移动后的状态。
最后直接搜就好了。


代码

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iomanip>
#include <cmath>
using namespace std;

const int dx[4][5] = {
    
     {
    
    }, {
    
     0, 0, 0, -2, 1 }, {
    
     0, 1, -1, 0, 0 }, {
    
     0, 0, 0, 2, -1 } };
const int dy[4][5] = {
    
     {
    
    }, {
    
     0, 1, -2, 0, 0 }, {
    
     0, 0, 0, 2, -1 }, {
    
     0, 1, -1, 0, 0 } };
const int dt[4][5] = {
    
     {
    
    }, {
    
     0, 2, 2, 3, 3 }, {
    
     0, 2, 2, 1, 1 }, {
    
     0, 3, 3, 1, 1 } };

char lyx[600][600];
bool flag = 0;
int n, m, h, t, tx, ty, v[600][600][4];

struct c {
    
    
    int x, y, t, c;
} a[6000000];

bool check(int x, int y, int t) {
    
    
    if (x < 1 || y < 1 || x > n || y > m || v[x][y][t] == 1)
        return 0;
    if (t == 1) {
    
    
        if (lyx[x][y] == '#' || lyx[x][y] == 'E')
            return 0;
    }
    if (t == 2) {
    
    
        if (lyx[x][y] == '#' || lyx[x][y + 1] == '#' || y + 1 > m)
            return 0;
    }
    if (t == 3) {
    
    
        if (lyx[x][y] == '#' || lyx[x + 1][y] == '#' || x + 1 > n)
            return 0;
    }
    return 1;
}

void bfs() {
    
    
    h = 0, t = 1;
    while (h < t) {
    
    
        h++;
        for (int i = 1; i <= 4; i++) {
    
    
            int xx = a[h].x + dx[a[h].t][i], yy = a[h].y + dy[a[h].t][i], tt = dt[a[h].t][i];
            if (check(xx, yy, tt)) {
    
    
                t++;
                v[xx][yy][tt] = 1;
                a[t].x = xx, a[t].y = yy, a[t].t = tt, a[t].c = a[h].c + 1;
                if (xx == tx && yy == ty && tt == 1) {
    
    
                    printf("%d\n", a[t].c);
                    return;
                }
            }
        }
    }
    printf("Impossible\n");
}

int main() {
    
    
    while (scanf("%d%d", &n, &m)) {
    
    
        memset(v, 0, sizeof(v));
        if (n == 0 && m == 0)
            break;
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++) cin >> lyx[i][j];
        flag = 0;
        for (int i = 1; i <= n; i++) {
    
    
            for (int j = 1; j <= m; j++) {
    
    
                if (lyx[i][j] == 'O')
                    tx = i, ty = j;
                if (lyx[i][j] == 'X' && !flag) {
    
    
                    a[1].x = i, a[1].y = j, flag = 1;
                    if (lyx[i][j + 1] == 'X')//状态2:横着躺着
                        a[1].t = 2;
                    else if (lyx[i + 1][j] == 'X')//状态3:竖着躺着
                        a[1].t = 3;
                    else
                        a[1].t = 1, v[i][j][a[i].t] = 1;//状态1:立着
                }
            }
        }
        bfs();
    }
}

猜你喜欢

转载自blog.csdn.net/kejin2019/article/details/113002327