Масив монет і запити зважування#223

Масив монет і запити зважування

1 секунда
256 мегабайтів
Дуже складна

Це інтерактивна задача.

Є монет, розташованих в ряд та пронумерованих зліва направо цілими числами від до .

Рівно (k<n) з цих монет є фальшивими, інші (n-k) монет — справжні. Фальшиві монети легші за справжні. Всі справжні монети мають однакову вагу, в той час як фальшиві монети можуть мати різну вагу. Також відомо, що фальшиві монети розташовані поспіль, тобто мають номери p, p+1, \dots, (p+k-1).

Вам потрібно знайти номер найлівішої фальшивої монети. Ви можете користуватись зважуванням, що аналогічне зважуванню на двочашкових терезах: вибрати дві множини монет, що не перетинаються, і дізнатись, яка з множин важить більше, або що множини важать однаково.

Вхідні дані

У першому рядку задано три цілі числа , , (1 \le k < n \le 10^4, 0 \le g \le 6) — загальна кількість монет, кількість фальшивих монет та номер блоку тестів відповідно.

Взаємодія

Щоб виконати запит зважування виведіть «? s_1 s_2 a_1 a_2 a_{s_1} b_1 b_2 b_{s_2}», де s_1 та s_2 позначають розміри множин які зважуються, а масиви та позначають номери монет, що належать першій та другій множинам відповідно.

У відповідь на запит програма журі виведе одне ціле число (x \in \{0,1,2\}). Якщо x = 1, то перша множина важча за другу; якщо x = 2, то друга множина важча за першу; якщо x = 0, то множини мають однакову вагу.

Якщо запит невалідний (тобто перевищено максимальну кількість запитів або параметри запиту є невалідними), програма журі виведе -1 та припинить роботу. У такому випадку завершіть роботу програми, щоб отримати вердикт Неправильна відповідь.

Подбайте про виклик методу flush після виводу кожного рядка. Для цього можна використовувати:

  • fflush(stdout), cout << endl або cout.flush() в C++;

  • System.out.flush() в Java;

  • flush(output) в Pascal;

  • sys.stdout.flush() в Python;

  • дивіться документації для інших мов програмування.

Вихідні дані

Для того, щоб дати відповідь, виведіть єдиний рядок у форматі «! », де (1 \leq p \leq n) — номер найлівішої фальшивої монети.

Приклади

Приклад

Вхідні дані
4 1 0

0

0

2
Вихідні дані

? 1 1 1 2

? 1 1 2 4

? 1 1 3 4

! 3

Оцінювання

Визначимо як максимальну кількість запитів зважування, яку ви можете виконати у тестах певного блоку.

  1. ( балів): n \le 16, q=16;

  2. ( балів): k=1, q=16;

  3. ( балів): k=1, q=11;

  4. ( балів): k \le 16, q=11;

  5. ( балів): ваги всіх фальшивих монет однакові, q=11;

  6. (до балів): q=300. Нехай максимальна кількість використаних зважувань дорівнює . Якщо c \le 9, то ви отримаєте бали, а інакше ви отримаєте \lfloor 54 \cdot \max(-0.0004 \cdot c + 0.3134, 0.018 + \frac{9.0773}{c}) \rfloor балів.

Код на мові C++, який обчислює кількість балів за останній блок тестів залежно від кількості використаних зважувань:

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

Таблиця розподілу балів

c \leq 17

Кількість балів

18 \leq c \leq 27

Кількість балів

28 \leq c \leq 300

Кількість балів

-

-

-

-

-

-

-

-

-