제출 #1251670

#제출 시각아이디문제언어결과실행 시간메모리
1251670jwvg0425세계 지도 (IOI25_worldmap)C++20
72 / 100
53 ms5448 KiB
#include "worldmap.h" #include <stdio.h> #include <vector> #include <queue> #include <algorithm> #include <iostream> #include <string> #include <bitset> #include <map> #include <set> #include <tuple> #include <string.h> #include <math.h> #include <random> #include <functional> #include <assert.h> #define all(x) (x).begin(), (x).end() #define xx first #define yy second using namespace std; template<typename T, typename Pr = less<T>> using pq = priority_queue<T, vector<T>, Pr>; using i64 = long long int; using ii = pair<int, int>; using ii64 = pair<i64, i64>; vector<int> edges[45]; int d[45], h[45]; struct RectBoard { RectBoard(int c, int s) : color(c), sz(s), depth(0), coverC(0) {} int color; int sz; int depth; int coverC = 0; ~RectBoard() { for (auto& [k, p] : childs) delete p; } void add_child(int x, int y, RectBoard* r) { childs.emplace_back(ii(x, y), r); depth = max(depth, r->depth + 1); if (childs.size() == 1) coverC = childs[0].yy->coverC + 1; } vector<pair<ii, RectBoard*>> childs; void paint(vector<vector<int>>& res, int x, int y) { for (int i = x; i < x + sz; i++) for (int j = y; j < y + sz; j++) res[i][j] = color; for (auto& [p, c] : childs) c->paint(res, x + p.xx, y + p.yy); } int cover() { // cover 필요 없는 경우 if (childs.empty()) return 0; if (childs[0].xx.xx != 0 && childs[0].xx.yy != 0) return 0; auto csz = childs[0].yy->cover() + 1; childs[0].xx.xx += 1; childs[0].xx.yy += 1; sz += csz; for (int i = 1; i < childs.size(); i++) { childs[i].xx.xx += csz; childs[i].xx.yy += csz; } return csz; } bool isAdj(ii p) { for (auto& [cp, v] : childs) { int lx = cp.xx - 1; int rx = cp.xx + v->sz; int ly = cp.yy - 1; int ry = cp.yy + v->sz; if (p.xx >= lx && p.xx <= rx && p.yy >= ly && p.yy <= ry) return true; } return false; } vector<ii> getCells() { vector<ii> res; for (int y = sz - 2; y >= 0; y-= 1) { for (int x = y % 2; x < sz - 1; x += 2) { if (isAdj(ii(x, y))) continue; res.emplace_back(x, y); } } return res; } }; void arrange(vector<RectBoard*>& childs) { int minCoverC = 0; int idx = 0; for (int i = 0; i < childs.size(); i++) { if (childs[i]->coverC > minCoverC) { minCoverC = childs[i]->coverC; idx = i; } } swap(childs[0], childs[idx]); } void predfs(int root) { for (auto& c : edges[root]) { if (d[c] != -1) continue; d[c] = d[root] + 1; predfs(c); h[root] = max(h[root], h[c] + 1); } } RectBoard* dfs(int root, bool maxFirst) { vector<int> backEdges; vector<RectBoard*> childBoards; if (maxFirst) sort(all(edges[root]), [](int l, int r) { return h[r] < h[l]; }); else sort(all(edges[root]), [](int l, int r) { return h[l] < h[r]; }); for (auto& c : edges[root]) { if (d[c] < d[root]) continue; // back edge 여부 체크 if (d[c] != d[root] + 1) backEdges.push_back(c); else { auto dfsr = dfs(c, maxFirst); if (dfsr->sz == 1) { backEdges.push_back(dfsr->color); delete dfsr; } else { childBoards.push_back(dfsr); } maxFirst = false; } } // leaf node if (childBoards.empty() && backEdges.empty()) return new RectBoard(root, 1); for (int i = 1; i < childBoards.size(); i++) { // 왼쪽 위 감싸기 childBoards[i]->cover(); } // 자식을 한 칸씩 띄고 배치할 수 있을 만큼으로 크기 지정 int sz = childBoards.size(); for (auto& c : childBoards) sz += c->sz; auto res = new RectBoard(root, sz); int x = 0, y = 0; for (auto& c : childBoards) { if (c == nullptr) continue; res->add_child(x, y, c); x += c->sz + 1; } // back edge 칸 계산 while (true) { vector<ii> cells = res->getCells(); if (cells.size() < backEdges.size()) { res->sz += 2; continue; } for (int i =0;i < backEdges.size(); i++) res->add_child(cells[i].xx, cells[i].yy, new RectBoard(backEdges[i], 1)); break; } return res; } vector<vector<int>> create_map(int N, int M, vector<int> A, vector<int> B) { for (int i = 1; i <= N; i++) edges[i].clear(); memset(d, -1, sizeof(d)); memset(h, 0, sizeof(h)); for (int i = 0; i < M; i++) { edges[A[i]].push_back(B[i]); edges[B[i]].push_back(A[i]); } d[1] = 0; predfs(1); auto res = dfs(1, true); vector<vector<int>> ans(res->sz, vector<int>(res->sz)); res->paint(ans, 0, 0); delete res; return ans; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...