UVa 1600 - Patrol Robot

contents

  1. 1. Problem
  2. 2. Sample Input
  3. 3. Sample Output
  4. 4. Solution

Problem

機器人能轉移只有上下左右四個方向,機器人切換快速移動模式,將自己跨過小於等於 K 個連續的障礙物。也就是說,當障礙物連續出現形成一座厚牆時,機器人就爬不過去。

求最少移動次數。

Sample Input

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
3
2 5
0
0 1 0 0 0
0 0 0 1 0
4 6
1
0 1 1 0 0 0
0 0 1 0 1 1
0 1 1 1 1 0
0 1 1 1 0 0
2 2
0
0 1
1 0

Sample Output

1
2
3
7
10
-1

Solution

將每一點多一個狀態 s,表示當前經過連續 s 個障礙物。如果下一個轉移地點不是障礙物,則 s 會歸零。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
int g[32][32];
int dist[32][32][32];
const int dx[] = {0, 0, 1, -1};
const int dy[] = {1, -1, 0, 0};
int main() {
int testcase;
int N, M, K;
scanf("%d", &testcase);
while (testcase--) {
scanf("%d %d %d", &N, &M, &K);
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++)
scanf("%d", &g[i][j]);
memset(dist, 63, sizeof(dist));
dist[0][0][0] = 0;
queue<int> X, Y, S;
int x, y, s, tx, ty, ts;
X.push(0), Y.push(0), S.push(0);
while (!X.empty()) {
x = X.front(), X.pop();
y = Y.front(), Y.pop();
s = S.front(), S.pop();
for (int i = 0; i < 4; i++) {
tx = x + dx[i], ty = y + dy[i];
if (tx < 0 || ty < 0 || tx >= N || ty >= M)
continue;
if (g[tx][ty])
ts = s + 1;
else
ts = 0;
if (ts > K) continue;
if (dist[tx][ty][ts] > dist[x][y][s] + 1) {
dist[tx][ty][ts] = dist[x][y][s] + 1;
X.push(tx), Y.push(ty), S.push(ts);
}
}
}
int ret = 0x3f3f3f3f;
for (int i = 0; i <= K; i++)
ret = min(ret, dist[N-1][M-1][i]);
printf("%d\n", ret == 0x3f3f3f3f ? -1 : ret);
}
return 0;
}
/*
3
2 5
0
0 1 0 0 0
0 0 0 1 0
4 6
1
0 1 1 0 0 0
0 0 1 0 1 1
0 1 1 1 1 0
0 1 1 1 0 0
2 2
0
0 1
1 0
*/