Submission #397408

#TimeUsernameProblemLanguageResultExecution timeMemory
397408KoDWorm Worries (BOI18_worm)C++17
44 / 100
1520 ms19376 KiB
#include <bits/stdc++.h>

template <class T>
using Vec = std::vector<T>;

int N, M, K, Q;
std::map<std::tuple<int, int, int>, int> memo;

int query(const int i, const int j, const int k) {
    std::tuple<int, int, int> tup(i, j, k);
    const auto itr = memo.find(tup);
    if (itr != memo.end()) {
        return itr -> second;
    }
    std::cout << "? " << i << ' ' << j << ' ' << k << std::endl;
    int ret;
    std::cin >> ret;
    assert(ret != -1);
    memo.emplace(std::move(tup), ret);
    return ret;
}

void answer(const int i, const int j, const int k) {
    std::cout << "! " << i << ' ' << j << ' ' << k << std::endl;
    std::exit(EXIT_SUCCESS);
}

template <class Select>
int fib_search(const int N, const Select& less) {
    Vec<int> fib(2, 1);
    while (fib.back() < N + 1) {
        const auto tmp = fib[fib.size() - 1] + fib[fib.size() - 2];
        fib.push_back(tmp);
    }
    int l = 0, r = N + 1, k = (int) fib.size() - 1;
    while (r - l > 2) {
        k -= 1;
        const auto m1 = r - fib[k];
        const auto m2 = l + fib[k];
        if (less(m1, m2)) {
            l = m1;
        }
        else {
            r = m2;
        }
    }
    return l + 1;
}

int main() {
    std::cin >> N >> M >> K >> Q;
    if (M == 1 and K == 1) {
        const auto ans = fib_search(N, [&](const int i, const int j) {
            if (j > N) return false;
            return query(i, 1, 1) <= query(j, 1, 1); 
        });
        answer(ans, 1, 1);
    }
    else if (K == 1) {
        const auto find_max = [&](const int i) {
            int ret = 1;
            for (int j = 2; j <= M; ++j) {
                if (query(i, ret, 1) < query(i, j, 1)) {
                    ret = j;
                }
            }
            return ret;
        };
        const auto ans = fib_search(N, [&](const int i, const int j) {
            if (j > N) return false;
            const auto x = find_max(i);
            const auto y = find_max(j);
            return query(i, x, 1) <= query(j, y, 1);
        });
        answer(ans, find_max(ans), 1);
    }
    else {
        const auto find_max = [&](const int i) {
            int retj = 1, retk = 1;
            for (int j = 1; j <= M; ++j) {
                for (int k = 1; k <= K; ++k) {
                    if (query(i, retj, retk) < query(i, j, k)) {
                        retj = j;
                        retk = k;
                    }
                }
            }
            return std::make_pair(retj, retk);
        };
        const auto ans = fib_search(N, [&](const int i, const int j) {
            if (j > N) return false;
            const auto [x, y] = find_max(i);
            const auto [z, w] = find_max(j);
            return query(i, x, y) <= query(j, z, w);
        });
        const auto [x, y] = find_max(ans);
        answer(ans, x, y);
    }
    return 0;
}
#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...