poj1475

嵌套式bfs 感觉算是一道比较难的爆搜

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
#define MAXN 25
 
int dir[4][2] = {-1, 0, 0, -1, 1, 0, 0, 1};
int vis_box[MAXN][MAXN], vis_player[MAXN][MAXN];
char map[MAXN][MAXN];
int r, c, px, py, bx, by;
char box_path[5] = "NWSE";
char player_path[5] = "nwse";
string temp_ans;
struct Player{
    int x, y;
    string path;
};
struct Box{
    int x, y;
    int px, py;
    string path;
};
 
bool ok(int x, int y) {
    if(x >= 0 && x < r && y >= 0 && y < c) {
        return true;
    }
    return false;
}
 
bool Player_BFS(int sx, int sy, int ex, int ey, int tx, int ty) {//这六个参数的意思就是人的初始位置横纵坐标,要到达的位置的横纵坐标,还有就是箱子此刻的位置坐标
    temp_ans = "";//记录离开箱子,人走的路径
    if(ex < 0 || ex >= r || ey < 0 || ey >= c) {
        return false;
    }
    Player start;
    start.x = sx;
    start.y = sy;
    start.path = "";
    memset(vis_player, 0, sizeof(vis_player));
    vis_player[sx][sy] = 1;
    queue<Player>Q;
    Q.push(start);
    while(!Q.empty()) {
        Player hd = Q.front();
        Q.pop();
        if(hd.x == ex && hd.y == ey) {
            temp_ans = hd.path;
            return true;
        }
        for(int i = 0; i < 4; ++ i) {
            int x = hd.x + dir[i][0];
            int y = hd.y + dir[i][1];
            if(x == tx && y == ty) {
                continue;
            }
            if(ok(x, y) && !vis_player[x][y]) {
                if(map[x][y] != '#') {
                    vis_player[x][y] = 1;
                    Player t;
                    t.x = x;
                    t.y = y;
                    t.path = hd.path + player_path[i];
                    Q.push(t);
                }
            }
        }
    }
    return false;
}
 
void Box_BFS() {
    memset(vis_box, 0, sizeof(vis_box));
    Box start;
    start.x = bx;
    start.y = by;
    start.px = px;
    start.py = py;
    start.path = "";
    vis_box[bx][by] = 1;
    queue<Box>Q;
    Q.push(start);
    while(!Q.empty()) {
        Box hd = Q.front();
        Q.pop();
        for(int i = 0; i < 4; ++ i) {
            int x = hd.x + dir[i][0];
            int y = hd.y + dir[i][1];
            if(ok(x, y) && !vis_box[x][y]) {
                if(map[x][y] != '#') {//这里开始以为只要map[i][j] == '.'||map[i][j] == 'T'就可以,但是后来明白由于位置的变化之前标记为'S'或者'B'的点也是可以走的
                    if(Player_BFS(hd.px, hd.py, hd.x - dir[i][0], hd.y - dir[i][1], hd.x, hd.y)) {
                        Box t;
                        t.x = x;
                        t.y = y;
                        t.px = hd.x;
                        t.py = hd.y;
                        vis_box[x][y] = 1;
                        t.path = hd.path + temp_ans + box_path[i];
                        if(map[x][y] == 'T') {
                            cout << t.path << endl;
                            return;
                        } else {
                            Q.push(t);
                        }
                    }
                }
            }
        }
    }
    printf("Impossible.\n");
}
 
int main() {
   
    int cnt = 0;
    while(scanf("%d%d", &r, &c), r) {
        for(int i = 0; i < r; ++ i) {
            scanf("%s", map[i]);
            for(int j = 0; j < c; ++ j) {
                if(map[i][j] == 'S') {
                    px = i;
                    py = j;
                }
                if(map[i][j] == 'B') {
                    bx = i;
                    by = j;
                }
            }
        }
        printf("Maze #%d\n", ++ cnt);
        Box_BFS();
        printf("\n");
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值