제출 #1368123

#제출 시각아이디문제언어결과실행 시간메모리
1368123llm세계 지도 (IOI25_worldmap)C++20
72 / 100
25 ms4284 KiB
#include <vector>
#include <algorithm>
#include <cmath>

using namespace std;

struct Item {
    vector<vector<int>> grid;
    int h, w, x, y;
};

struct Builder {
    vector<vector<int>> tree_children;
    vector<vector<int>> fake_children;

    vector<vector<int>> build(int u) {
        vector<Item> items;
        // Recursively build grids for all real children in the spanning tree
        for (int v : tree_children[u]) {
            vector<vector<int>> g = build(v);
            items.push_back({g, (int)g.size(), (int)g[0].size(), 0, 0});
        }
        // Add 1x1 blocks for non-tree edges to satisfy remaining adjacencies
        for (int v : fake_children[u]) {
            items.push_back({{{v}}, 1, 1, 0, 0});
        }

        // Base case: leaf node with no non-tree edges needing placement
        if (items.empty()) {
            return {{u}};
        }

        // Sort items by height descending for shelf bin packing
        sort(items.begin(), items.end(), [](const Item& a, const Item& b) {
            return a.h > b.h;
        });

        int total_area = 0;
        int max_W = 2;
        for (auto& item : items) {
            total_area += (item.w + 1) * (item.h + 1);
            max_W = max(max_W, item.w + 2);
        }
        // Target a roughly square boundary to minimize K
        max_W = max(max_W, (int)ceil(sqrt(total_area * 1.5)));

        int cx = 1, cy = 1;
        int shelf_H = 0;
        int max_x = 1, max_y = 1;

        // Shelf packing logic to tightly pack children
        for (auto& item : items) {
            if (cx > 1 && cx + item.w > max_W) {
                cx = 1;
                cy += shelf_H + 1; // Move to the next shelf
                shelf_H = 0;
            }
            item.x = cx;
            item.y = cy;
            max_x = max(max_x, cx + item.w);
            max_y = max(max_y, cy + item.h);
            shelf_H = max(shelf_H, item.h);
            cx += item.w + 1; // 1 unit of padding to prevent children from touching
        }

        int box_H = max_y + 1;
        int box_W = max_x + 1;

        // Create the parent grid filled with the parent's color
        vector<vector<int>> G(box_H, vector<int>(box_W, u));

        // Blit the child grids onto the parent grid
        for (auto& item : items) {
            for (int i = 0; i < item.h; ++i) {
                for (int j = 0; j < item.w; ++j) {
                    G[item.y + i][item.x + j] = item.grid[i][j];
                }
            }
        }

        return G;
    }
};

vector<vector<int>> create_map(int N, int M, vector<int> A, vector<int> B) {
    Builder builder;
    builder.tree_children.resize(N + 1);
    builder.fake_children.resize(N + 1);

    vector<vector<int>> adj(N + 1);
    for (int i = 0; i < M; ++i) {
        adj[A[i]].push_back(B[i]);
        adj[B[i]].push_back(A[i]);
    }

    // BFS to find a spanning tree
    vector<bool> visited(N + 1, false);
    vector<int> q;
    q.push_back(1);
    visited[1] = true;

    int head = 0;
    vector<pair<int, int>> tree_edges;
    while(head < q.size()) {
        int u = q[head++];
        for (int v : adj[u]) {
            if (!visited[v]) {
                visited[v] = true;
                builder.tree_children[u].push_back(v);
                tree_edges.push_back({u, v});
                tree_edges.push_back({v, u});
                q.push_back(v);
            }
        }
    }

    // Identify non-tree edges and assign them as "fake children"
    for (int i = 0; i < M; ++i) {
        int u = A[i], v = B[i];
        bool is_tree = false;
        for (auto& te : tree_edges) {
            if (te.first == u && te.second == v) {
                is_tree = true; break;
            }
        }
        if (!is_tree) {
            builder.fake_children[u].push_back(v);
        }
    }

    // Build the grid recursively starting from the root (country 1)
    vector<vector<int>> map_grid = builder.build(1);

    // Expand to make it a perfect K x K square matrix
    int max_dim = max((int)map_grid.size(), (int)map_grid[0].size());
    vector<vector<int>> final_map(max_dim, vector<int>(max_dim, 1));
    for (int i = 0; i < map_grid.size(); ++i) {
        for (int j = 0; j < map_grid[0].size(); ++j) {
            final_map[i][j] = map_grid[i][j];
        }
    }

    return final_map;
}
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…