Submission #381227

#TimeUsernameProblemLanguageResultExecution timeMemory
381227fishy15Soccer (JOI17_soccer)C++17
100 / 100
537 ms23388 KiB
#include <iostream> #include <iomanip> #include <fstream> #include <vector> #include <array> #include <algorithm> #include <utility> #include <map> #include <queue> #include <set> #include <cmath> #include <cstdio> #include <cstring> #define ll long long #define ld long double #define eps 1e-8 #define MOD 1000000007 #define INF 0x3f3f3f3f #define INFLL 0x3f3f3f3f3f3f3f3f // change if necessary #define MAXN 100010 #define MAXW 510 using namespace std; int h, w; ll a, b, c; int n; array<int, 2> players[MAXN]; priority_queue<array<ll, 4>, vector<array<ll, 4>>, greater<array<ll, 4>>> pq; // {dist, x, y, dir} int dx[4] = {1, 0, -1, 0}; int dy[4] = {0, -1, 0, 1}; bool walk_set[MAXW][MAXW]; ll walk_dist[MAXW][MAXW]; // 0-3 refer to dir kicked from, corresponds to directions above // 5 is min cost while keeping the ball ll dist[MAXW][MAXW][5]; bool ok(int x, int y, int dir, ll d) { return x >= 0 && y >= 0 && x < h && y < w && d < dist[x][y][dir]; } bool ok_walk(int x, int y) { return x >= 0 && y >= 0 && x < h && y < w && !walk_set[x][y]; } void set_dist(ll d, int x, int y, int dir) { if (dist[x][y][dir] < d) return; if (dir < 4) { int nx = x + dx[dir]; int ny = y + dy[dir]; // continue the kick if (ok(nx, ny, dir, d + a)) { dist[nx][ny][dir] = d + a; pq.push({d + a, nx, ny, dir}); } // get picked up by person if (ok(x, y, 4, d + walk_dist[x][y])) { dist[x][y][4] = d + walk_dist[x][y]; pq.push({d + walk_dist[x][y], x, y, 4}); } } else { // walk to adjacent square for (int i = 0; i < 4; i++) { int nx = x + dx[i]; int ny = y + dy[i]; if (ok(nx, ny, 4, d + c)) { dist[nx][ny][4] = d + c; pq.push({d + c, nx, ny, 4}); } } // kick in some direction for (int i = 0; i < 4; i++) { if (ok(x, y, i, d + b)) { dist[x][y][i] = d + b; pq.push({d + b, x, y, i}); } } } } void calc_walk() { queue<array<int, 2>> q; for (int i = 0; i < n; i++) { auto [x, y] = players[i]; walk_set[x][y] = true; q.push({x, y}); } while (!q.empty()) { auto [x, y] = q.front(); q.pop(); for (int i = 0; i < 4; i++) { int nx = x + dx[i]; int ny = y + dy[i]; if (ok_walk(nx, ny)) { walk_dist[nx][ny] = walk_dist[x][y] + c; walk_set[nx][ny] = true; q.push({nx, ny}); } } } } void calc_dist() { pq.push({0, players[0][0], players[0][1], 4}); memset(dist, 0x3f, sizeof dist); dist[players[0][0]][players[0][1]][4] = 0; while (!pq.empty()) { auto [d, x, y, dir] = pq.top(); pq.pop(); set_dist(d, x, y, dir); } } int main() { cin.tie(0)->sync_with_stdio(0); cin >> h >> w; cin >> a >> b >> c; cin >> n; h++; w++; for (int i = 0; i < n; i++) { int s, t; cin >> s >> t; players[i] = {s, t}; } calc_walk(); calc_dist(); cout << dist[players[n - 1][0]][players[n - 1][1]][4] << '\n'; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...