P1126 机器人搬重物_复杂bfs

P1126 机器人搬重物 传送门

说实话这道题蛮复杂度, 需要注意的东西比较多.

  • 机器人是球形且有直径,它的中心是点而非方格. 所以可以选定一个方格作为机器人的位置
  • 一个障碍物直接占满一个格子,而同样因为机器人的直径问题,不能到这些格子的格点上去, 需要特殊判断
  • 在移动时机器人不能跨过障碍物,即遇到障碍物就必须停止。可用break直接实现.

对于一个坐标, 可能有四个方向的情况, 所以vis数组用三维来表示.

机器人的旋转和方向是用num%4来表示的, num为0代表向南, 为1代表向东, 为2代表向北, 为3代表向西, 那么只要我根据前一个状态的方向num, 调整num(+1或-1), 然后取模, 就可以得到现在的方向.

此题对条件的判断稍复杂, 需要非常细心. 索性第一次提交90分, 发现起点就是终点这种情况没有考虑进去.

#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <queue>
#define MP(x, y) make_pair(x, y)
using namespace std;
typedef pair<int, int> II;

const int maxn = 55;
int n, m, sx, sy, ex, ey, num;
int mov[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
int map[maxn][maxn], vis[maxn][maxn][4];
char start;

bool bfs()
{
    vis[sx][sy][num % 4] = 0;
    queue<pair<II, int> > Q;
    Q.push(make_pair(MP(sx, sy), num % 4));
    while (!Q.empty()) {
        pair<II, int> now = Q.front();
        Q.pop();
        int x = now.first.first, y = now.first.second;
        num = now.second;
        for (int i = 1, u, v, w; i <= 3; ++i) {
            u = x + i * mov[num % 4][0];
            v = y + i * mov[num % 4][1];
            w = now.second;
            if (u < 1 || u >= n || v < 1 || v >= m || vis[u][v][w]) continue;
            if (map[u][v] || map[u][v + 1] || map[u + 1][v] || map[u + 1][v + 1]) break;
            vis[u][v][w] = vis[x][y][w] + 1;
            if (u == ex && v == ey) return true;
            Q.push(make_pair(MP(u, v), num % 4));
        }
        if (!vis[x][y][(num + 1) % 4]) {
            vis[x][y][(num + 1) % 4] = vis[x][y][num] + 1;
            Q.push(make_pair(MP(x, y), (num + 1) % 4));
        }
        if (num == 0) num = 4;
        if (!vis[x][y][(num - 1) % 4]) {
            vis[x][y][(num - 1) % 4] = vis[x][y][num] + 1;
            Q.push(make_pair(MP(x, y), (num - 1) % 4));
        }
    }
    return false;
}

int main()
{
    cin >> n >> m;
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            cin >> map[i][j];
        }
    }
    cin >> sx >> sy >> ex >> ey >> start;
    if (start == 'S') num = 0;
    else if (start == 'E') num = 1;
    else if (start == 'N') num = 2;
    else if (start == 'W') num = 3;
    memset(vis, 0, sizeof(vis));
    if (sx == ex && sy == ey) {
        cout << 0;
        return 0;
    }
    bfs();
    for (int i = 0; i < 4; ++i) {
        if (vis[ex][ey][i]) {
            cout << vis[ex][ey][i];
            return 0;
        }
    }
    cout << -1;
}

猜你喜欢

转载自blog.csdn.net/wjh2622075127/article/details/81417368