Skip to content

Commit 1b1d9f9

Browse files
committed
Dodano rozwiązanie zadania 'Bomberman' z XXIX OI
1 parent cb2b9a7 commit 1b1d9f9

File tree

1 file changed

+122
-0
lines changed
  • rozwiazania/xxix/etap2/dzien2/bom

1 file changed

+122
-0
lines changed
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
// Rozwiązanie zadania 'Bomberman' z II Etapu XXIX OI.
2+
// Autor: Paweł Putra
3+
// Złożoność czasowa: O(n^2)
4+
// Złożoność pamięciowa: O(n^2)
5+
// Punkty: 100 (upsolve)
6+
7+
#include <bits/stdc++.h>
8+
#define dbg(x) #x << " = " << x << " "
9+
using namespace std;
10+
constexpr int MAXN = 1005;
11+
12+
vector<pair<int,int>> ruchy = {
13+
{1, 0},
14+
{-1, 0},
15+
{0, 1},
16+
{0, -1}
17+
};
18+
19+
string s[MAXN];
20+
pair<int,int> P, K;
21+
22+
array<int, 4> from[MAXN][MAXN][3][3];
23+
char kierunek(int x, int y) {
24+
if (x == 1) return 'D';
25+
if (x == -1) return 'G';
26+
if (y == 1) return 'P';
27+
return 'L';
28+
}
29+
30+
int32_t main() {
31+
ios_base::sync_with_stdio(0);
32+
int n;
33+
cin >> n;
34+
for (int i = 1; i <= n; i++) {
35+
cin >> s[i];
36+
for (int j = 1; j <= n; j++) {
37+
if (s[i][j-1] == 'P') P = {i, j};
38+
if (s[i][j-1] == 'K') K = {i, j};
39+
}
40+
}
41+
42+
43+
44+
// Idę sobie, nie detonowałem żadnych bomb - w pewnym momencie
45+
// napotykam zamurowane pole - mogę na nie wejść stawiając bombę:
46+
// nie muszę decydować gdzie dokładnie - ale muszę zdecydować czy w tej kolumnie
47+
// czy w wierszu.
48+
// Wtedy mogę chodzić po cegłach
49+
// Stan:
50+
// - gdzie jestem - (x, y)
51+
// - {0 - mogę zmienić, 1 - chodzę po, 2 - nie mogę zmienić} x na którym stoi bomba.
52+
// - {0 - mogę zmienić, 1 - chodzę po, 2 - nie mogę zmienić} y na którym stoi bomba.
53+
54+
queue<array<int, 4>> q;
55+
q.push({P.first, P.second, 0, 0});
56+
from[P.first][P.second][0][0] = {-1, -1, -1, -1};
57+
while (!q.empty()) {
58+
auto [x, y, rx, ry] = q.front();
59+
60+
if (x == K.first && y == K.second) {
61+
string res;
62+
63+
// To wypiszę jak będą bomby wymagające zakrętu na mojej ścieżce.
64+
int bx = 0, by = 0;
65+
pair<int,int> bomba;
66+
while (from[x][y][rx][ry][0] != -1) {
67+
auto [px, py, prx, pry] = from[x][y][rx][ry];
68+
if (rx == 1) bx = x;
69+
if (ry == 1) by = y;
70+
res += kierunek(x - px, y - py);
71+
x = px;
72+
y = py;
73+
rx = prx;
74+
ry = pry;
75+
76+
if (s[x][y-1] == '#') bomba = {x, y};
77+
78+
}
79+
cout << res.size() << "\n";
80+
// To wypiszę jak wszystkie bomby ze ścieżki są na jednej linii.
81+
if (!bx || !by) tie(bx, by) = bomba;
82+
// A to wypiszę jak nie ma żadnej bomby.
83+
if (!bx || !by) tie(bx, by) = P;
84+
cout << bx << " " << by << "\n";
85+
reverse(res.begin(), res.end());
86+
cout << res << "\n";
87+
return 0;
88+
}
89+
90+
auto relax = [&](int x, int y, int rx, int ry) {
91+
if (x < 1 || x > n || y < 1 || y > n) return;
92+
if (s[x][y-1] == 'X') return;
93+
if (s[x][y-1] == '#' && rx != 1 && ry != 1) return;
94+
95+
if (!from[x][y][rx][ry][0]) {
96+
from[x][y][rx][ry] = q.front();
97+
q.push({x, y, rx, ry});
98+
}
99+
};
100+
101+
for (auto [dx, dy] : ruchy) {
102+
int nx = x + dx;
103+
int ny = y + dy;
104+
// Bomby jeszcze nie było.
105+
if (rx + ry == 0) {
106+
// Nie stawiam bomby.
107+
relax(nx, ny, 0, 0);
108+
109+
// Stawiam bombę (ale tylko na jednym wymiarze).
110+
relax(nx, ny, 0, 1);
111+
relax(nx, ny, 1, 0);
112+
} else if (y != ny) {
113+
relax(nx, ny, (rx == 0 ? 1 : rx), (ry == 1 ? 2 : ry));
114+
} else if (x != nx) {
115+
relax(nx, ny, (rx == 1 ? 2 : rx), (ry == 0 ? 1 : ry));
116+
}
117+
}
118+
q.pop();
119+
}
120+
121+
cout << "NIE\n";
122+
}

0 commit comments

Comments
 (0)