-
코드트리: 왕실의 기사 대결문제해결 2023. 10. 25. 17:25
왕실의 기사 대결
10월 15일 오전, 고사장에 가서 푼 문제이다.
기출 중 메이즈러너 이 문제가 가장 최신 기출이었는데, 이것 보다는 풀만해서 다행이었다.
그래도 코드트리가 메이즈러너랑 왕실의 기사 대결가 같은 골드3 티어라고 해주니 기분이 좋다.
#include <bits/stdc++.h> #include <unordered_map> using namespace std; #define pii pair<int, int> #define endl "\n" #define FOR(i, N) for (int i = 0; i < int(N); i++) #define FORL(e, S) for (auto& e : S) #define iib(r, c) (0 <= r && r < L && 0 <= c && c < L) int dr[4] = { -1, +0, +1, +0 }; int dc[4] = { +0, +1, +0, -1 }; int L, N, Q; int AMAP[40][40]; int RMAP[40][40]; struct Robot { enum Status { alive, dead }; Status status = alive; pii pos; int idx, h, w, k, dmg = 0; Robot(int idx, int r, int c, int h, int w, int k) { this->pos = make_pair(r, c); this->idx = idx, this->h = h, this->w = w, this->k = k; } bool can_push(int dir, vector<Robot>& vRobo) { unordered_map<int, int> um; vector<pii> vp; switch (dir) { case 0: FOR(i, this->w) vp.emplace_back(pos.first - 1, pos.second + i); break; case 1: FOR(i, this->h) vp.emplace_back(pos.first + i, pos.second + w); break; case 2: FOR(i, this->w) vp.emplace_back(pos.first + h, pos.second + i); break; case 3: FOR(i, this->h) vp.emplace_back(pos.first + i, pos.second - 1); break; } FORL(p, vp) { // 칸 외부이거나 벽임 if (!iib(p.first, p.second) || AMAP[p.first][p.second] == 2) return false; if (RMAP[p.first][p.second] != -1) um[RMAP[p.first][p.second]] += 1; } bool ret = true; FORL(p, um) { ret = (ret && vRobo[p.first].can_push(dir, vRobo)); } return ret; } void move(int dir, bool kill_mode) { int r, c; tie(r, c) = pos; int nr = r + dr[dir], nc = c + dc[dir]; FOR(i, h) FOR(j, w) RMAP[r + i][c + j] = -1; if (kill_mode) { FOR(i, h) FOR(j, w) if (AMAP[nr + i][nc + j] == 1) dmg += 1; if (dmg >= k) status = dead; } if (status != dead) { pos = make_pair(nr, nc); FOR(i, h) FOR(j, w) RMAP[nr + i][nc + j] = idx; } } void push(int dir, vector<Robot>& vRobo, bool kill_mode) { unordered_map<int, int> um; vector<pii> vp; switch (dir) { case 0: FOR(i, this->w) vp.emplace_back(pos.first - 1, pos.second + i); break; case 1: FOR(i, this->h) vp.emplace_back(pos.first + i, pos.second + w); break; case 2: FOR(i, this->w) vp.emplace_back(pos.first + h, pos.second + i); break; case 3: FOR(i, this->h) vp.emplace_back(pos.first + i, pos.second - 1); break; } FORL(p, vp) { if (RMAP[p.first][p.second] != -1) um[RMAP[p.first][p.second]] += 1; } FORL(p, um) { vRobo[p.first].push(dir, vRobo, true); } move(dir, kill_mode); } }; int main() { cin >> L >> N >> Q; FOR(i, L) FOR(j, L) cin >> AMAP[i][j]; memset(RMAP, -1, sizeof(int) * 40 * 40); vector<Robot> vRobo; FOR(i, N) { int r, c, h, w, k; cin >> r >> c >> h >> w >> k; r -= 1, c -= 1; vRobo.emplace_back(i, r, c, h, w, k); FOR(ii, h) FOR(jj, w) RMAP[r + ii][c + jj] = i; } vector<pii> vOrders; FOR(i, Q) { int idx, dir; cin >> idx >> dir; vOrders.emplace_back(idx - 1, dir); } FORL(e, vOrders) { int ridx, dir; tie(ridx, dir) = e; if (vRobo[ridx].status == vRobo[ridx].dead) continue; if (vRobo[ridx].can_push(dir, vRobo)) vRobo[ridx].push(dir, vRobo, false); } int ans = 0; FORL(r, vRobo) { if (r.status == r.alive) ans += r.dmg; } cout << ans << endl; return 0; }
'문제해결' 카테고리의 다른 글
백준 10830번: 행렬 제곱 (0) 2023.10.25 백준 9663번: N-Queen (0) 2023.10.25 코드트리: 싸움땅 (0) 2023.10.25 코드트리: 코드트리 빵 (0) 2023.10.25 백준 1005번: ACM Craft (0) 2023.10.25