Submission #1271318

#TimeUsernameProblemLanguageResultExecution timeMemory
1271318model_codeTelepathy (JOI25_telepathy)C++20
100 / 100
70 ms980 KiB
// 5.99d turns solution for general cases #include "telepathy.h" #include <algorithm> #include <iostream> // make adjacency list std::vector<std::vector<int> > make_graph(int N, const std::vector<int>& A, const std::vector<int>& B) { std::vector<std::vector<int> > G(N); for (int i = 0; i < N - 1; i++) { G[A[i]].push_back(B[i]); G[B[i]].push_back(A[i]); } return G; } // find centroid of tree std::vector<int> find_centroid(int N, const std::vector<std::vector<int> >& G) { std::vector<int> res; std::vector<int> subsize(N, 1); auto dfs = [&](auto& self, int x, int pre) -> void { bool ok = true; for (int i : G[x]) { if (i != pre) { self(self, i, x); subsize[x] += subsize[i]; if (subsize[i] * 2 > N) { ok = false; } } } if (ok && subsize[x] * 2 >= N) { res.push_back(x); } }; dfs(dfs, 0, -1); return res; } // find S-T path on tree std::vector<int> find_path(int N, std::vector<std::vector<int> > G, int S, int T) { std::vector<int> par(N, -1); auto dfs = [&](auto& self, int x, int pre) -> void { par[x] = pre; for (int i : G[x]) { if (i != pre) { self(self, i, x); } } }; dfs(dfs, T, -1); std::vector<int> seq = {S}; while (seq.back() != T) { seq.push_back(par[seq.back()]); } return seq; } // sequence of changes of (depth of A) - (depth of B) std::vector<int> instruction(int N, int player) { double mul = 1.0; std::vector<int> seq; int turn = 0, l = 0, r = 0; while (int(seq.size()) < 10 * N) { if (turn == 0) { int nr = int(mul); int pre = l; for (int i = l + 1; i <= r; i++) { if ((i & 1) == 0) { seq.push_back(i - pre); pre = i; } } seq.push_back((r + 1) - pre); for (int i = r + 2; i <= nr; i++) { seq.push_back(+1); } r = nr; } else { int nl = -int(mul); int pre = r; for (int i = r - 1; i >= l; i--) { if ((i & 1) == 1) { seq.push_back(i - pre); pre = i; } } seq.push_back((l - 1) - pre); for (int i = l - 2; i >= nl; i--) { seq.push_back(-1); } l = nl; } turn ^= 1; mul *= 1.685; } seq.resize(10 * N); std::vector<int> res(10 * N); for (int i = 0; i < 10 * N; i++) { if (player == 0) { res[i] = (seq[i] >= +1 ? +1 : seq[i] == -2 ? -1 : 0); } else { res[i] = (seq[i] <= -1 ? +1 : seq[i] == +2 ? -1 : 0); } } return res; } // Aitana's strategy std::vector<int> Aitana(int N, std::vector<int> A, std::vector<int> B, int S, int subtask) { std::vector<std::vector<int> > G = make_graph(N, A, B); std::vector<int> centroids = find_centroid(N, G); std::vector<int> path; for (int i : centroids) { std::vector<int> subpath = find_path(N, G, S, i); if (path.empty() || path.size() > subpath.size()) { path = subpath; } } std::vector<int> seq = instruction(N, 0); std::vector<int> res(10 * N + 1, -1); res[0] = S; int pos = 0; for (int i = 0; i < 10 * N; i++) { pos += seq[i]; res[i + 1] = path[std::max(std::min(pos, int(path.size()) - 1), 0)]; } return res; } // Bruno's strategy std::vector<int> Bruno(int N, std::vector<int> C, std::vector<int> D, int T, int subtask) { std::vector<std::vector<int> > G = make_graph(N, C, D); std::vector<int> centroids = find_centroid(N, G); std::vector<int> path; for (int i : centroids) { std::vector<int> subpath = find_path(N, G, T, i); if (path.empty() || path.size() > subpath.size()) { path = subpath; } } std::vector<int> seq = instruction(N, 1); std::vector<int> res(10 * N + 1, -1); res[0] = T; int pos = 0; for (int i = 0; i < 10 * N; i++) { pos += seq[i]; res[i + 1] = path[std::max(std::min(pos, int(path.size()) - 1), 0)]; } for (int i = 1; i <= 10 * N; i++) { if (centroids.size() == 2 && res[i - 1] == path.back() && (i == 10 * N || res[i + 1] == path.back())) { res[i] = centroids[0] + centroids[1] - path.back(); } } return res; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...