제출 #676832

#제출 시각아이디문제언어결과실행 시간메모리
676832CyanmondWorm Worries (BOI18_worm)C++17
69 / 100
512 ms3420 KiB
#include <bits/stdc++.h> std::map<std::tuple<int, int, int>, int> memo; int W; int query(int x, int y = 0, int z = 0) { if (std::min({x, y, z}) < 0 or std::max({x, y, z}) >= W) { return 0; } if (memo.find({x, y, z}) != memo.end()) { return memo[{x, y, z}]; } std::cout << '?' << ' ' << x + 1 << ' ' << y + 1 << ' ' << z + 1 << std::endl; int res; std::cin >> res; if (res == -1) { std::exit(0); } memo[{x, y, z}] = res; return res; } int finish(int x, int y = 0, int z = 0) { std::cout << '!' << ' ' << x + 1 << ' ' << y + 1 << ' ' << z + 1 << std::endl; std::exit(0); } void solve1() { // fib search int l = -1, r = W; int x = 1, y = 1; while (l + y < r) { x += y; std::swap(x, y); } r = l + y; while (x > 1) { y -= x; if (query(l + y) < query(r - y)) { l += y; } else { r -= y; } std::swap(x, y); } finish(l + x); } void solve2() { int xl = 0, xr = W, yl = 0, yr = W; while (std::max(xr - xl, yr - yl) > 1) { if (yr - yl > 1) { const auto ym = (yl + yr) / 2; int ma = -1, ma_id = -1; for (int i = xl; i < xr; ++i) { const int v = query(i, ym); if (v > ma) { ma = v; ma_id = i; } } const int v2_a = query(ma_id, ym - 1), v2_b = query(ma_id, ym + 1); if (v2_a > ma) { yr = ym; } else if (v2_b > ma) { yl = ym + 1; } else { finish(ma_id, ym); } } if (xr - xl > 1) { const auto xm = (xl + xr) / 2; int ma = -1, ma_id = -1; for (int i = yl; i < yr; ++i) { const int v = query(xm, i); if (v > ma) { ma = v; ma_id = i; } } const int v2_a = query(xm - 1, ma_id), v2_b = query(xm + 1, ma_id); if (v2_a > ma) { xr = xm; } else if (v2_b > ma) { xl = xm + 1; } else { finish(xm, ma_id); } } } finish(xl, yl); } constexpr std::array<std::tuple<int, int, int>, 6> dxyz = {{{0, 0, 1}, {0, 0, -1}, {0, 1, 0}, {0, -1, 0}, {1, 0, 0}, {-1, 0, 0}}}; void solve3(int Q) { int best = -1; int x = 0, y = 0, z = 0; std::random_device seed_gen; std::mt19937 engine(seed_gen()); std::uniform_int_distribution dist(0, W); for (int i = 0; i < Q / 6; ++i) { --Q; const int nx = dist(engine), ny = dist(engine), nz = dist(engine); const int v = query(nx, ny, nz); if (v > best) { best = v; x = nx, y = ny, z = nz; } } while (Q > 0) { for (const auto &[ax, ay, az] : dxyz) { if (Q == 0) { break; } --Q; const auto nx = x + ax, ny = y + ay, nz = z + az; if (std::min({nx, ny, nz}) < 0 or std::max({nx, ny, nz}) >= W) { continue; } const int v = query(nx, ny, nz); if (v > best) { best = v; x = nx, y = ny, z = nz; break; } } } finish(x, y, z); } int main() { int N, M, K, Q; std::cin >> N >> M >> K >> Q; W = N; if (M == 1) { solve1(); } else if (K == 1) { solve2(); } else { solve3(Q); } }
#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...