Problem: icpc2023_bapc_k
Difficulty: easy
Categories: search
Time limit: 2000 ms, memory limit: 256 MB

The king of Belle Aire People’s Country has come up with a new plan: he has heard about the popular phenomenon called “King of the Hill”, and he would like to become one as well. To do so, he has ordered you to raise a flag on the highest hill in his square kingdom, which has dimensions $n \times n$ . You are given a very expensive (it is gold- and jewel-embedded) satellite-based height-measuring system. This equipment is highly accurate: the heights on every location in the kingdom are represented with distinct integers. However, to cut costs, you are only allowed to take $1 0 n + 1 0 0$ measurements before reporting back to the king.

![](images/e56c7d9411a009439bd288d2d989442952202d61019c8f0b716b35b9fba291c2.jpg)  
Raising the flag, Linglie Hill, Selkirk. CC BY-SA 2.0 by Jim Barton on Wikimedia Commons

Furthermore, you know for certain that there is only a single point that is the absolute highest: this is the only point for which its height is larger than the (up to) four orthogonally adjacent points that lie inside the kingdom. In other words, there are no local maxima besides the global maximum.

# Interaction

This is an interactive problem. Your submission will be run against an interactor, which reads from the standard output of your submission and writes to the standard input of your submission. This interaction needs to follow a specific protocol:

The interactor first sends one line with an integer $n$ ( $1 \leq n \leq 1 0 0 0 0$ ), the width and height of the kingdom.

Then, your program should make at most $1 0 n + 1 0 0$ queries to find the highest point in the kingdom. Each query is made by printing one line of the form $\textit { \textbf { * } ? } \textit { x } \textit { y } ^ { \flat }$ ( $1 \leq x , y \leq n$ ). The interactor will respond with an integer $\boldsymbol { v }$ ( $1 \le v \le 1 0 ^ { 9 }$ ), indicating the height at coordinate $( x , y )$ .

When you have determined the height of the highest point in the kingdom $v$ , print one line of the form “! $v$ ”, after which the interaction will stop. Printing the answer does not count as a query.

The interactor is not adaptive: the heights in the kingdom are fixed up front, and do not depend on your queries.

Make sure you flush the buffer after each write.

A testing tool is provided to help you develop your solution.

Using more than $1 0 n + 1 0 0$ queries will result in a wrong answer.

![](images/1996fe64e572c5dbfd79d13eedec283d76eda4fc28b8613861c2c5c938ea4604.jpg)

Non-adaptive interactor (C++):
#include "testlib.h"
#include <bits/stdc++.h>

using namespace std;


static long long queries = 0;
static long long query_limit = 0;


static void log_metrics() {
    try {
        
        tout << "queries=" << queries << endl;
        tout << "query_limit=" << query_limit << endl;
    } catch (...) {
        
    }
}


static void finish(TResult verdict, const string& msg) {
    log_metrics();
    quitf(verdict, "%s", msg.c_str());
}


int N;
int px, py;
long long wx, wy;
int type; 
long long noise_seed; 





long long get_height(int x, int y) {
    if (x < 1 || x > N || y < 1 || y > N) return -1;
    
    long long dist_cost = 0;
    long long dx = abs(x - px);
    long long dy = abs(y - py);
    
    if (type == 0) {
        
        
        dist_cost = wx * dx + wy * dy;
    } else {
        
        
        dist_cost = wx * dx * dx + wy * dy * dy;
    }
    
    
    
    
    long long max_h = 1000000000LL;
    long long h = max_h - dist_cost;
    
    
    
    
    if (h < 1) h = 1;
    
    return h;
}

int main(int argc, char** argv) {
    
    registerInteraction(argc, argv);
    
    
    atexit(log_metrics);
    
    
    
    
    
    
    
    N = inf.readInt(1, 10000, "n");
    px = inf.readInt(1, N, "px");
    py = inf.readInt(1, N, "py");
    
    wx = inf.readLong(1LL, 10000LL, "wx");
    wy = inf.readLong(1LL, 10000LL, "wy");
    type = inf.readInt(0, 1, "type");
    noise_seed = inf.readLong(0LL, 2000000000LL, "noise_seed");
    
    
    
    query_limit = 10LL * N + 100;
    
    
    cout << N << endl;
    
    
    
    long long hard_cap = 2 * query_limit + 2000;
    
    while (true) {
        
        if (queries > hard_cap) {
            finish(_pe, "Hard query limit exceeded (infinite loop protection)");
        }
        
        
        string token;
        if (!(cin >> token)) {
            finish(_pe, "Unexpected EOF while reading query/answer");
        }
        
        
        if (token == "!") {
            long long ans;
            if (!(cin >> ans)) {
                finish(_pe, "Expected answer integer after '!'");
            }
            
            
            long long correct_h = get_height(px, py);
            if (ans == correct_h) {
                finish(_ok, "Correct peak height found");
            } else {
                string msg = "Wrong answer: expected " + to_string(correct_h) + ", got " + to_string(ans);
                finish(_wa, msg);
            }
        }
        
        else {
            int x, y;
            
            
            if (token == "?") {
                if (!(cin >> x >> y)) {
                    finish(_pe, "Expected coordinates after '?'");
                }
            } else {
                
                try {
                    x = stoi(token);
                } catch (...) {
                    finish(_pe, "Invalid token (expected '!', '?', or integer): " + token);
                }
                if (!(cin >> y)) {
                    finish(_pe, "Expected y coordinate");
                }
            }
            
            
            queries++;
            
            
            if (queries % 50 == 0) log_metrics();
            
            long long h = get_height(x, y);
            if (h == -1) {
                finish(_wa, "Query coordinates out of bounds: " + to_string(x) + " " + to_string(y));
            }
            
            
            cout << h << endl;
        }
    }
    
    return 0;
}


Adaptive interactor (C++):

Test generator (C++):
#include "testlib.h"
#include <bits/stdc++.h>

using namespace std;

int main(int argc, char* argv[]) {
    registerGen(argc, argv, 1);

    
    string mode = opt<string>("mode", "non");
    int seed_val = atoi(argv[1]);

    int n;

    
    if (seed_val == 1) n = 1;
    else if (seed_val == 2) n = 2;
    else if (seed_val == 3) n = 10000; 
    else if (seed_val == 4) n = 10000; 
    else if (seed_val == 5) n = 10000; 
    else {
        
        int p = rnd.next(100);
        if (p < 5) n = rnd.next(1, 10);
        else if (p < 15) n = rnd.next(11, 100);
        else if (p < 40) n = rnd.next(101, 1000);
        else n = rnd.next(1001, 10000);
    }

    if (mode == "adp") {
        
        cout << n << "\n";
        cout << rnd.next(1, 2000000000) << "\n";
    } else {
        
        int px = rnd.next(1, n);
        int py = rnd.next(1, n);

        
        if (seed_val == 4) { px = 1; py = 1; }
        else if (seed_val == 5) { px = n; py = n; }
        else if (seed_val == 6) { px = 1; py = n; }
        else if (seed_val == 7) { px = n/2 + 1; py = n/2 + 1; }

        
        
        
        int type = rnd.next(0, 1);
        
        long long wx, wy;
        if (type == 1) {
            
            
            wx = rnd.next(1, 8);
            wy = rnd.next(1, 8);
        } else {
            
            
            wx = rnd.next(1, 10000);
            wy = rnd.next(1, 10000);
        }

        long long noise_seed = rnd.next(1, 2000000000);

        
        
        
        
        cout << n << "\n";
        cout << px << " " << py << "\n";
        cout << wx << " " << wy << " " << type << " " << noise_seed << "\n";
    }

    return 0;
}