P1126 机器人搬重物

点击查看代码
#include <iostream>
#include <queue>
#include <cstring>

using namespace std;

const int MAXN = 55;

//存储原始地图
int raw_map[MAXN][MAXN];

//存储机器人能否站在这个节点上的矩阵
bool bad[MAXN][MAXN];

// 访问标记数组:vis[x][y][dir]
// dir: 0=N, 1=E, 2=S, 3=W
int dist[MAXN][MAXN][4];

//方向数组,按照上北下南左西右东的顺序
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};

struct Node {
    int x, y, dir, step;
};

int n, m;

// 预处理地图:将“格子障碍”转化为“格点不可达”
void build_map() {
    
    //机器人和障碍物都有体积,以障碍物为节点的右下角组成的正方形都不可走
    // 1.首先边界都不能走
    for (int i = 0; i <= n; i++) bad[i][0] = bad[i][m] = true;
    for (int j = 0; j <= m; j++) bad[0][j] = bad[n][j] = true;

    //2.遍历每一个格子,标记对应的位置都不可走
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (raw_map[i][j] == 1) {
                // 如果当前格子是障碍,则周围四个角(格点)都无法作为机器人的中心
                bad[i-1][j-1] = true;
                bad[i-1][j]   = true;
                bad[i][j-1]   = true;
                bad[i][j]     = true;
            }
        }
    }
}

int bfs(int sx, int sy, int s_dir, int ex, int ey) {

    //启动与初始化
    queue<Node> q;
    memset(dist, -1, sizeof(dist));
    q.push({sx, sy, s_dir, 0});
    dist[sx][sy][s_dir] = 0;
    //开始循环
    while (!q.empty()) {
        //取出
        Node u = q.front();
        q.pop();

        // 终点判断
        if (u.x == ex && u.y == ey) {
            return u.step;
        }

        //观察邻居,左转向
        int left_dir = (u.dir + 3) % 4;
        if (dist[u.x][u.y][left_dir] == -1) {
            dist[u.x][u.y][left_dir] = u.step + 1;
            q.push({u.x, u.y, left_dir, u.step + 1});
        }

        //观察邻居,右转向
        int right_dir = (u.dir + 1) % 4;
        if (dist[u.x][u.y][right_dir] == -1) {
            dist[u.x][u.y][right_dir] = u.step + 1;
            q.push({u.x, u.y, right_dir, u.step + 1});
        }

        // 3. 观察邻居,尝试向前走
        for (int k = 1; k <= 3; k++) {
            int nx = u.x + dx[u.dir] * k;
            int ny = u.y + dy[u.dir] * k;

            //判断与入队,边界
            if (nx < 1 || nx >= n || ny < 1 || ny >= m) break;

            //判断与入队,障碍物
            if (bad[nx][ny]) break;

            // 判断与入队,还要没去过
            if (dist[nx][ny][u.dir] == -1) {
                dist[nx][ny][u.dir] = u.step + 1;
                q.push({nx, ny, u.dir, u.step + 1});
            }
        }
    }

    return -1; // 无法到达
}

int main() {
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            cin >> raw_map[i][j];
        }
    }

    // 构建格点地图 (处理 bad 数组)
    build_map();

    //读入起点和终点
    int sx, sy, ex, ey;
    char d_char;
    cin >> sx >> sy >> ex >> ey >> d_char;

    // 将字符方向转换为数字
    int s_dir;
    if (d_char == 'N') s_dir = 0;
    else if (d_char == 'E') s_dir = 1;
    else if (d_char == 'S') s_dir = 2;
    else if (d_char == 'W') s_dir = 3;
    
    cout << bfs(sx, sy, s_dir, ex, ey) << endl;

    return 0;
}
posted @ 2026-01-13 17:22  AnoSky  阅读(5)  评论(0)    收藏  举报