Problem: icpc2025_world_finals_i
Difficulty: medium
Categories: greedy, data structures
Time limit: 2000 ms, memory limit: 256 MB

Imperial Chance & Play Casino offers games using a slot machine that has $n$ wheels arranged next to each other. Each of the wheels has $n$ distinct symbols on it, and these symbols appear in the same order on each wheel. Each wheel shows one of its symbols through a window on the front of the machine, which results in a sequence of $n$ symbols being shown next to each other.

![](images/d11cceeb619ece1f029930fcf0fc4a93e1c49676c6791b6f0856c419b6201179.jpg)  
Figure I.1: The initial configuration in Sample Interaction 1.

You are standing behind the machine and notice that a maintenance panel has been left open. When you stick your hand inside, you are able to secretly rotate any of the wheels by any number of steps, thus changing the symbol shown on that wheel. You want to win a jackpot, which will happen if all the wheels show the same symbol at the same time. Unfortunately, you cannot see the symbols from your position, so you asked your good friend to help you. The friend is standing in front of the machine and she tells you the number of distinct symbols in the sequence she can currently see. Can you win the jackpot by manipulating the wheels if your friend updates the information after every action you make?

# Interaction

The first line of input contains an integer $n$ $3 \leq n \leq 5 0$ ), giving the number of wheels and symbols in the machine.

Interaction then proceeds in rounds. In each round, one line of input becomes available, containing an integer $k$ $( 1 \leq k \leq n )$ , the number of distinct symbols in the current sequence. If $k > 1$ , output two integers $i$ and $j$ $\ 1 \leq i \leq n$ ; $- 1 0 ^ { 9 } \le j \le 1 0 ^ { 9 } )$ , representing your action: rotating the $i ^ { \mathrm { t h } }$ wheel by $j$ positions, where negative numbers indicate rotating in the opposite direction. Otherwise, if $k = 1$ , indicating that all wheels show the same symbol, your program must exit without printing more output.

At most 10 000 actions are allowed – if your submission uses more rounds, it will not be accepted. It is guaranteed that the initial configuration of wheels does not already have all wheels showing the same symbol ( $k > 1$ in the first round).

The judge program will not behave in an adversarial way, which means the initial configuration is fixed before the first action.

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

ICPC International Collegiate Programming Contest

# The 2025 ICPC World Finals Baku

31 August - 5 September 2025 //hosted by ADA University

<table><tr><td rowspan=2 colspan=2>Read                                     Sample Interaction 1                                     Write5</td></tr><tr><td rowspan=1 colspan=1>5</td></tr><tr><td rowspan=1 colspan=1></td><td rowspan=1 colspan=1>11</td></tr><tr><td rowspan=1 colspan=1>3</td><td rowspan=1 colspan=1></td></tr><tr><td rowspan=1 colspan=1></td><td rowspan=1 colspan=1>42</td></tr><tr><td rowspan=1 colspan=1>3</td><td rowspan=1 colspan=1></td></tr><tr><td rowspan=1 colspan=1></td><td rowspan=1 colspan=1>31</td></tr><tr><td rowspan=1 colspan=1>3</td><td rowspan=1 colspan=1></td></tr><tr><td rowspan=1 colspan=1></td><td rowspan=1 colspan=1>31</td></tr><tr><td rowspan=1 colspan=1>2</td><td rowspan=1 colspan=1></td></tr><tr><td rowspan=1 colspan=1></td><td rowspan=1 colspan=1>54</td></tr><tr><td rowspan=1 colspan=1>1</td><td rowspan=1 colspan=1></td></tr></table>

<table><tr><td rowspan=2 colspan=2>Read                                     Sample Interaction 2                                     Write33</td></tr><tr><td rowspan=1 colspan=1>33</td></tr><tr><td rowspan=1 colspan=1></td><td rowspan=1 colspan=1>2-1</td></tr><tr><td rowspan=1 colspan=1>2</td><td rowspan=1 colspan=1></td></tr><tr><td rowspan=1 colspan=1></td><td rowspan=1 colspan=1>3-1</td></tr><tr><td rowspan=1 colspan=1>2</td><td rowspan=1 colspan=1></td></tr><tr><td rowspan=1 colspan=1></td><td rowspan=1 colspan=1>2-1</td></tr><tr><td rowspan=1 colspan=1>1</td><td rowspan=1 colspan=1></td></tr></table>

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



static long long queries = 0;

static const long long QUERY_LIMIT = 10000; 



static const long long HARD_CAP = 200000; 




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 count_distinct(int n, const vector<int>& s) {
    
    static vector<bool> seen;
    if (seen.size() < (size_t)n) seen.resize(n);
    fill(seen.begin(), seen.begin() + n, false);
    
    int distinct = 0;
    for (int x : s) {
        if (x >= 0 && x < n) {
            if (!seen[x]) {
                seen[x] = true;
                distinct++;
            }
        }
    }
    return distinct;
}

int main(int argc, char** argv) {
    
    registerInteraction(argc, argv);
    
    
    atexit(log_metrics);

    
    
    int n = inf.readInt();
    
    if (n < 1) quitf(_fail, "Invalid n in input file");

    vector<int> s(n);
    for (int i = 0; i < n; i++) {
        s[i] = inf.readInt();
    }
    
    
    cout << n << endl; 

    
    while (true) {
        
        int k = count_distinct(n, s);
        cout << k << endl;

        
        if (k == 1) {
            finish(_ok, "All wheels show the same symbol.");
        }

        
        if (queries >= HARD_CAP) {
            finish(_pe, "Hard query limit exceeded (possible infinite loop).");
        }

        
        if (queries > 0 && queries % 10 == 0) {
            log_metrics();
        }

        
        
        string token;
        if (!(cin >> token)) {
            finish(_wa, "Unexpected EOF while waiting for action");
        }

        
        if (token == "?") {
            if (!(cin >> token)) {
                finish(_wa, "Expected index i after '?'");
            }
        } else if (!token.empty() && token[0] == '!') {
            
            finish(_wa, "Unexpected token '!'. Protocol expects actions until k=1.");
        }

        
        int i_idx = -1;
        try {
            size_t end_pos = 0;
            long long val = stoll(token, &end_pos);
            if (end_pos != token.size()) finish(_wa, "Garbage found in index token");
            
            
            if (val < 1 || val > n) {
                finish(_wa, "Index i is out of bounds [1, " + to_string(n) + "]");
            }
            i_idx = (int)val;
        } catch (...) {
            finish(_wa, "Invalid integer format for index i");
        }

        
        long long j_steps = 0;
        if (!(cin >> j_steps)) {
            finish(_wa, "Expected integer for rotation j");
        }

        
        if (abs(j_steps) > 1000000000LL) {
             finish(_wa, "Rotation j out of range [-10^9, 10^9]");
        }

        
        queries++;

        
        
        int v_idx = i_idx - 1;
        long long current_val = s[v_idx];
        
        
        
        long long next_val = (current_val + j_steps) % n;
        if (next_val < 0) next_val += n;
        
        s[v_idx] = (int)next_val;
    }

    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 specified_n = opt<int>("n", -1);

    
    
    int n;
    int seed_val = atoi(argv[1]);

    if (specified_n != -1) {
        n = specified_n;
    } else {
        if (seed_val == 1) n = 3;       
        else if (seed_val == 2) n = 50; 
        else if (seed_val == 3) n = 4;  
        else if (seed_val == 4) n = 5;  
        else n = rnd.next(3, 50);       
    }

    
    if (mode == "adp") {
        cout << n << endl;
        return 0;
    }

    
    vector<int> s(n);
    
    
    
    
    
    
    
    
    int strategy = rnd.next(0, 4);

    if (strategy == 0) {
        
        for (int i = 0; i < n; i++) {
            s[i] = rnd.next(0, n - 1);
        }
    } else if (strategy == 1) {
        
        for (int i = 0; i < n; i++) s[i] = i;
        
        for (int i = 1; i < n; i++) {
            int j = rnd.next(0, i);
            swap(s[i], s[j]);
        }
    } else if (strategy == 2) {
        
        int v1 = rnd.next(0, n - 1);
        int v2 = rnd.next(0, n - 1);
        while (v1 == v2) v2 = rnd.next(0, n - 1);
        for (int i = 0; i < n; i++) {
            s[i] = (rnd.next(2) ? v1 : v2);
        }
    } else if (strategy == 3) {
        
        int common = rnd.next(0, n - 1);
        fill(s.begin(), s.end(), common);
        int idx = rnd.next(0, n - 1);
        int diff = rnd.next(0, n - 1);
        while (diff == common) diff = rnd.next(0, n - 1);
        s[idx] = diff;
    } else {
        
        for (int i = 0; i < n; i++) {
            s[i] = rnd.next(0, n - 1);
        }
    }

    
    
    bool all_same = true;
    for (int i = 1; i < n; i++) {
        if (s[i] != s[0]) {
            all_same = false;
            break;
        }
    }

    if (all_same) {
        int idx = rnd.next(0, n - 1);
        s[idx] = (s[idx] + 1) % n;
    }

    
    cout << n << endl;
    for (int i = 0; i < n; i++) {
        cout << s[i] << (i == n - 1 ? "" : " ");
    }
    cout << endl;

    return 0;
}