제출 #551714

#제출 시각아이디문제언어결과실행 시간메모리
551714tranxuanbachWorm Worries (BOI18_worm)C++17
100 / 100
517 ms5208 KiB
#include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> using namespace std; using namespace __gnu_pbds; // #define endl '\n' #define fi first #define se second #define For(i, l, r) for (auto i = (l); i < (r); i++) #define ForE(i, l, r) for (auto i = (l); i <= (r); i++) #define FordE(i, l, r) for (auto i = (l); i >= (r); i--) #define Fora(v, a) for (auto v: (a)) #define bend(a) (a).begin(), (a).end() #define isz(a) ((signed)(a).size()) using ll = long long; using ld = long double; using pii = pair <int, int>; using vi = vector <int>; using vpii = vector <pii>; using vvi = vector <vi>; mt19937 rando(chrono::steady_clock::now().time_since_epoch().count()); int randt(int l, int r, int k = 0){ if (k > 0){ return max(randt(l, r, k - 1), (int)(rando() % (r - l + 1)) + l); } if (k < 0){ return min(randt(l, r, k + 1), (int)(rando() % (r - l + 1)) + l); } return rando() % (r - l + 1) + l; } const int SMALL = 5; struct point3_t{ int x, y, z; point3_t(): x(0), y(0), z(0){ } point3_t(int x, int y, int z): x(x), y(y), z(z){ } friend bool operator< (const point3_t &lhs, const point3_t &rhs){ return tie(lhs.x, lhs.y, lhs.z) < tie(rhs.x, rhs.y, rhs.z); } }; int n, m, k, q; map <point3_t, int> mapquery; int query(point3_t a){ if (not (1 <= a.x and a.x <= n and 1 <= a.y and a.y <= m and 1 <= a.z and a.z <= k)){ return 0; } if (mapquery.count(a)){ return mapquery[a]; } q--; cout << "? " << a.x << ' ' << a.y << ' ' << a.z << endl; int ans; cin >> ans; return (mapquery[a] = ans); } int query(int x, int y = 1, int z = 1){ return query(point3_t(x, y, z)); } int query_if(point3_t a){ if (mapquery.count(a)){ return mapquery[a]; } return 0; } int query_if(int x, int y = 1, int z = 1){ return query_if(point3_t(x, y, z)); } void answer(point3_t a){ cout << "! " << a.x << ' ' << a.y << ' ' << a.z << endl; #ifdef FEXT cout << "Q " << q << endl; #endif exit(0); } void answer(int x, int y = 1, int z = 1){ answer(point3_t(x, y, z)); } namespace subtask1{ bool check(){ return m == 1 and k == 1; } ld phi = (sqrtl(5) - 1) / 2; void solve(){ int lo = 1, hi = n; int mid1 = (int)round(phi * (hi - lo)) + lo; while (lo < hi){ int mid2 = (lo + hi) - mid1; if (mid1 == mid2){ if (mid2 - 1 >= lo){ mid2--; } else{ mid2++; } } if (hi - lo + 1 >= 5 and abs(max(mid1, mid2) - ((int)round(phi * (hi - lo)) + lo)) >= 5){ mid1 = (int)round(phi * (hi - lo)) + lo; mid2 = (lo + hi) - mid1; } if (query(mid1) > query(mid2)){ if (mid1 < mid2){ hi = min(mid2, hi - 1); } else{ lo = max(mid2, lo + 1); } } else{ if (mid1 < mid2){ lo = max(mid1, lo + 1); } else{ hi = min(mid1, hi - 1); } mid1 = mid2; } } answer(lo); } } namespace subtask2{ bool check(){ return k == 1; } void solve(){ int lox = 1, hix = n, loy = 1, hiy = m; while (lox < hix or loy < hiy){ int lenx = hix - lox + 1, leny = hiy - loy + 1; int mid = -1, val1 = 0, val2 = 0, val3 = 0, val4 = 0, val5 = 0; if (lenx >= leny){ mid = (lox + hix) >> 1; ForE(y, loy, hiy){ val1 = max(val1, query_if(lox, y)); val2 = max(val2, query_if(hix, y)); } ForE(x, lox, hix){ if (x <= mid){ val1 = max({val1, query_if(x, loy), query_if(x, hiy)}); } else{ val2 = max({val2, query_if(x, loy), query_if(x, hiy)}); } } ForE(y, loy, hiy){ val3 = max(val3, query(mid, y)); } if (val3 <= max(val1, val2)){ if (val1 > val2){ hix = mid; } else{ lox = mid + 1; } continue; } int yy = -1; ForE(y, loy, hiy){ if (query(mid, y) == val3){ yy = y; val4 = max(val4, query(mid + 1, y)); val5 = max(val5, query(mid - 1, y)); break; } } if (val3 >= max(val4, val5)){ answer(mid, yy); } if (val4 < val5){ hix = mid; } else{ lox = mid + 1; } } else{ mid = (loy + hiy) >> 1; ForE(x, lox, hix){ val1 = max(val1, query_if(x, loy)); val2 = max(val2, query_if(x, hiy)); } ForE(y, loy, hiy){ if (y <= mid){ val1 = max({val1, query_if(lox, y), query_if(hix, y)}); } else{ val2 = max({val2, query_if(lox, y), query_if(hix, y)}); } } ForE(x, lox, hix){ val3 = max(val3, query(x, mid)); } if (val3 <= max(val1, val2)){ if (val1 > val2){ hiy = mid; } else{ loy = mid + 1; } continue; } int xx = -1; ForE(x, lox, hix){ if (query(x, mid) == val3){ xx = x; val4 = max(val4, query(x, mid + 1)); val5 = max(val5, query(x, mid - 1)); break; } } if (val3 >= max(val4, val5)){ answer(xx, mid); } if (val4 < val5){ hiy = mid; } else{ loy = mid + 1; } } } answer(lox, loy); } } namespace subtask3{ bool check(){ return 1; } int dx[6] = {-1, 1, 0, 0, 0, 0}; int dy[6] = {0, 0, -1, 1, 0, 0}; int dz[6] = {0, 0, 0, 0, -1, 1}; vi rd = {0, 1, 2, 3, 4, 5}; void solve(){ vector <pair <int, point3_t>> a; ForE(turn, 1, q / 2){ int x = randt(1, n), y = randt(1, m), z = randt(1, k); a.emplace_back(query(x, y, z), point3_t(x, y, z)); } sort(bend(a)); point3_t u = a.back().se; while (q){ if (q >= ((k + 9) / 10) * 2000){ pair <int, point3_t> mx = {-1, point3_t()}; For(d, 0, 6){ point3_t v = point3_t(u.x + dx[d], u.y + dy[d], u.z + dz[d]); mx = max(mx, make_pair(query(v), v)); } if (mx.fi > query(u)){ u = mx.se; } else{ answer(u); } } else{ shuffle(bend(rd), rando); bool ck = 1; For(i, 0, 6){ int d = rd[i]; point3_t v = point3_t(u.x + dx[d], u.y + dy[d], u.z + dz[d]); if (q and query(v) > query(u)){ u = v; ck = 0; break; } } if (ck){ answer(u); } } } answer(u); } } signed main(){ ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); // freopen("KEK.inp", "r", stdin); // freopen("KEK.out", "w", stdout); cin >> n >> m >> k >> q; if (subtask1::check()){ subtask1::solve(); return 0; } if (subtask2::check()){ subtask2::solve(); return 0; } if (subtask3::check()){ subtask3::solve(); return 0; } } /* ==================================================+ INPUT: | --------------------------------------------------| --------------------------------------------------| ==================================================+ OUTPUT: | --------------------------------------------------| --------------------------------------------------| ==================================================+ */
#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...