Submission #1352507

#TimeUsernameProblemLanguageResultExecution timeMemory
1352507vjudge1Park (BOI16_park)C++17
0 / 100
181 ms33360 KiB
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;

struct Tree {
    long long x, y, r;
};

struct Edge {
    int u, v;
    double dist;
    bool operator<(const Edge& other) const {
        return dist < other.dist;
    }
};

struct Visitor {
    int r, e, id;
};

struct DSU {
    vector<int> parent;
    DSU(int n) {
        parent.resize(n);
        for (int i = 0; i < n; ++i) parent[i] = i;
    }
    int find(int i) {
        if (parent[i] == i) return i;
        return parent[i] = find(parent[i]);
    }
    void unite(int i, int j) {
        int root_i = find(i);
        int root_j = find(j);
        if (root_i != root_j) parent[root_i] = root_j;
    }
    bool connected(int i, int j) {
        return find(i) == find(j);
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m;
    cin >> n >> m;
    long long w, h;
    cin >> w >> h;

    vector<Tree> trees(n);
    for (int i = 0; i < n; ++i) {
        cin >> trees[i].x >> trees[i].y >> trees[i].r;
    }

    vector<Edge> edges;
    for (int i = 0; i < n; ++i) {
        for (int j = i + 1; j < n; ++j) {
            double d = sqrt(pow(trees[i].x - trees[j].x, 2) + pow(trees[i].y - trees[j].y, 2));
            edges.push_back({i, j, d - trees[i].r - trees[j].r});
        }
    }

    for (int i = 0; i < n; ++i) {
        edges.push_back({i, n, (double)trees[i].y - trees[i].r});       
        edges.push_back({i, n + 1, (double)w - trees[i].x - trees[i].r}); 
        edges.push_back({i, n + 2, (double)h - trees[i].y - trees[i].r}); 
        edges.push_back({i, n + 3, (double)trees[i].x - trees[i].r});     
    }

    sort(edges.begin(), edges.end());

    vector<Visitor> visitors(m);
    for (int i = 0; i < m; ++i) {
        cin >> visitors[i].r >> visitors[i].e;
        visitors[i].id = i;
    }

    sort(visitors.begin(), visitors.end(), [](const Visitor& a, const Visitor& b) {
        return a.r < b.r;
    });

    vector<string> results(m);
    DSU dsu(n + 4);
    int edge_idx = 0;

    for (int i = 0; i < m; ++i) {
        double diameter = 2.0 * visitors[i].r;
        while (edge_idx < edges.size() && edges[edge_idx].dist < diameter) {
            dsu.unite(edges[edge_idx].u, edges[edge_idx].v);
            edge_idx++;
        }

        int e = visitors[i].e;
        bool b[4][4] = {false};
        for (int x = 0; x < 4; ++x) {
            for (int y = 0; y < 4; ++y) {
                if (dsu.connected(n + x, n + y)) b[x][y] = true;
            }
        }

        vector<bool> can_reach(5, false);
        can_reach[e] = true;

        auto is_blocked = [&](int start, int end) {
            if (start > end) swap(start, end);
            if (start == 1 && end == 2) return b[0][1] || b[0][2] || b[0][3];
            if (start == 2 && end == 3) return b[1][2] || b[1][3] || b[1][0];
            if (start == 3 && end == 4) return b[2][3] || b[2][0] || b[2][1];
            if (start == 4 && end == 1) return b[3][0] || b[3][1] || b[3][2];
            if (start == 1 && end == 3) return b[0][1] || b[0][2] || b[3][1] || b[3][2];
            if (start == 2 && end == 4) return b[0][3] || b[0][2] || b[1][3] || b[1][2];
            return false;
        };

        string res = "";
        for (int target = 1; target <= 4; ++target) {
            if (!is_blocked(e, target)) res += to_string(target);
        }
        results[visitors[i].id] = res;
    }

    for (const string& s : results) cout << s << "\n";

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...