#P12567. [UOI 2023] An Array of Coins and Weighing Requests

    ID: 14134 远端评测题 1000ms 256MiB 尝试: 0 已通过: 0 难度: (无) 上传者: 标签>2023交互题Special JudgeUOI(乌克兰)

[UOI 2023] An Array of Coins and Weighing Requests

题目描述

This is an interactive problem.

There are nn coins arranged in a row and numbered from 11 to nn from left to right.

Exactly kk (k<nk<n) of these coins are fake, and the other (nk)(n-k) coins are real. The fake coins are lighter than the real ones. All real coins have the same weight, while fake coins may have different weights. It is also known that the fake coins are consecutive\textbf{consecutive}, that is, they have indexes p,p+1,,(p+k1)p, p+1, \dots, (p+k-1).

You need to find the number of the leftmost fake coin. You can use weighing, which is similar to weighing on a two-pan balance scale: select two sets of non-intersecting coins and find out which set weighs more, or that the sets weigh the same.

Interactive Protocol

The first line contains three integers nn, kk, gg (1k<n1041 \le k < n \le 10^4, 0g60 \le g \le 6) - the total number of coins, the number of fake coins, and the test block number, respectively.

To perform the weighing request, output "?\texttt{?} s1s_1 s2s_2 a1a_1 a2a_2 \dots as1a_{s_1} b1b_1 b2b_2 \dots bs2b_{s_2}", where s1s_1 and s2s_2 denote the sizes of the sets being weighed, and the arrays aa and bb denote the numbers of the coins belonging to the first and second sets, respectively.

In response to the request, the jury program will output a single integer xx (x{0,1,2}x \in \{0,1,2\}). If x=1x = 1, then the first set is heavier than the second; if x=2x = 2, then the second set is heavier than the first; if x=0x = 0, then the sets have the same weight.

If the request is invalid (i.e., the maximum number of requests has been exceeded or the request parameters are invalid), the jury program will output -1\texttt{-1} and terminate. In this case, terminate your program to receive the verdict Wrong Answer\texttt{Wrong Answer}.

Be sure to call the flush\texttt{flush} method after outputting each line. You can use:

  • fflush(stdout)\texttt{fflush(stdout)}, cout << endl\texttt{cout <{}< endl}, or cout.flush()\texttt{cout.flush()} in C++\texttt{C++};
  • System.out.flush()\texttt{System.out.flush()} in Java\texttt{Java};
  • flush(output)\texttt{flush(output)} in Pascal\texttt{Pascal};
  • sys.stdout.flush()\texttt{sys.stdout.flush()} in Python\texttt{Python};
  • consult the documentation for other programming languages.

To give the answer, output a single line in the format "!\texttt{!} pp", where pp (1pn1 \leq p \leq n) is the number of the leftmost fake coin.

输入格式

See Interactive Protocol.

输出格式

See Interactive Protocol.

4 1 0

0

0

2

? 1 1 1 2

? 1 1 2 4

? 1 1 3 4

! 3

提示

Let's define qq as the maximum number of weighing queries you can make in the tests of a certain block.

  • (55 points): n16n \le 16, q=16q=16;
  • (99 points): k=1k=1, q=16q=16;
  • (77 points): k=1k=1, q=11q=11;
  • (1616 points): k16k \le 16, q=11q=11;
  • (99 points): all fake coins have the same weight, q=11q=11;
  • (up to 5454 points): q=300q=300. Let the maximum number of weighings used be cc. If c9c \le 9, you will get 5454 points, otherwise you will get $ \lfloor 54 \cdot \max(-0.0004 \cdot c + 0.3134, 0.018 + \frac{9.0773}{c}) \rfloor $ points.

Here is the C++\tt{C++} code that computes the number of points for the last block of tests depending on the number of weighings used:

((c <= 9) ? 54 : int(54 * (max((-0.0004 * c + 0.3134), (0.018 + 9.0773 / c)))))

Scoring table

$$\begin{array}{|c|c|c|c|c|c|} \hline c \leq 17 & \text{Points} & 18 \leq c \leq 27 & \text{Points} & 28 \leq c \leq 300 & \text{Points} \\ \hline \leq 9 & 54 & 18 & 28 & 28 & 18 \\ 10 & 49 & 19 & 26 & 29-30 & 17 \\ 11 & 45 & 20 & 25 & 31-42 & 16 \\ 12 & 41 & 21 & 24 & 43-89 & 15 \\ 13 & 38 & 22 & 23 & 90-135 & 14 \\ 14 & 35 & 23 & 22 & 136-181 & 13 \\ 15 & 33 & 24 & 21 & 182-227 & 12 \\ 16 & 31 & 25 & 20 & 228-274 & 11 \\ 17 & 29 & 26-27 & 19 & 275-300 & 10 \\ \hline \end{array}$$