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;
}