UVa 12881 - Ricochet Robots

contents

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

Problem

一款神秘的團隊遊戲,機器人需要彼此合作,使得 1 號機器人恰好停留在 X 上面。盤面最多給定 4 個機器人。

每一個時刻,最多有一個機器人進行移動,此時會將其他機器人視為障礙物,每次選擇其中一個方向,並且要移動到碰到障礙物為止。

在有限步數內找到一個最小步數,如果找不到輸出無解。

Sample Input

1
2
3
4
5
6
7
8
9
10
2 5 4 10
.2...
...W.
WWW..
.X.1.
1 5 4 10
.....
...W.
WWW..
.X.1.

Sample Output

1
2
6
NO SOLUTION

Solution

把多個機器人的座標作為一個狀態。狀態紀錄時,除了 1 號機器人外,其他機器人的座標視為集合看待,適當地減少搜索狀態。

跟預期想的相同,全搜索不致於造成狀態總數過大。

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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include <stdio.h>
#include <queue>
#include <map>
#include <algorithm>
using namespace std;
int N, W, H, L;
struct state {
pair<int, int> xy[4];
bool operator<(const state &a) const {
for (int i = 0; i < N; i++)
if (xy[i] != a.xy[i])
return xy[i] < a.xy[i];
return false;
}
void normal() {
sort(xy + 1, xy + N);
}
};
char g[16][16];
const int dx[] = {0, 0, 1, -1};
const int dy[] = {1, -1, 0, 0};
int isValid(int x, int y) {
return x >= 0 && y >= 0 && x < H && y < W;
}
int bfs(state init, int L) {
state u, v;
queue<state> Q;
map<state, int> R;
int x, y, tx, ty;
int used[11][11] = {}, testcase = 0;
init.normal();
Q.push(init), R[init] = 0;
while (!Q.empty()) {
u = Q.front(), Q.pop();
int step = R[u];
if (g[u.xy[0].first][u.xy[0].second] == 'X')
return step;
if (step > L)
continue;
testcase++;
for (int i = 0; i < N; i++) {
x = u.xy[i].first, y = u.xy[i].second;
used[x][y] = testcase;
}
for (int i = 0; i < N; i++) {
x = u.xy[i].first, y = u.xy[i].second;
for (int j = 0; j < 4; j++) {
tx = x, ty = y;
while (isValid(tx + dx[j], ty + dy[j])) {
if (g[tx + dx[j]][ty + dy[j]] == 'W')
break;
if (used[tx + dx[j]][ty + dy[j]] == testcase)
break;
tx += dx[j], ty += dy[j];
}
v = u, v.xy[i] = make_pair(tx, ty);
v.normal();
if (R.find(v) == R.end()) {
R[v] = step + 1;
Q.push(v);
}
}
}
}
return 0x3f3f3f3f;
}
int main() {
while (scanf("%d %d %d %d", &N, &W, &H, &L) == 4) {
for (int i = 0; i < H; i++)
scanf("%s", g[i]);
state init;
for (int i = 0; i < H; i++) {
for (int j = 0; j < W; j++) {
if (g[i][j] >= '1' && g[i][j] <= '9')
init.xy[g[i][j] - '1'] = make_pair(i, j);
}
}
int ret = bfs(init, L);
if (ret > L)
puts("NO SOLUTION");
else
printf("%d\n", ret);
}
return 0;
}
/*
2 5 4 10
.2...
...W.
WWW..
.X.1.
1 5 4 10
.....
...W.
WWW..
.X.1.
*/