This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#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 - 1, yl = 0, yr = W - 1;
while (xl != xr or yl != yr) {
if (yl != yr) {
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 - 1;
} 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 - 1;
} 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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |