Square or rectangle#186

Square or rectangle (Editorial)

Ключ до задачі — обмеження на площу: зафарбована ділянка займає не менше дошки, тобто щонайменше клітинок. Звідси випливає, що сторона квадрата не менша за : квадрат площею має сторону .

Крок 1: сітка запитів. Запитаємо всі точок з координатами з множини \{20, 40, 60, 80, 100\} по обох осях.

Чому цього достатньо? Кратні двадцяти йдуть рівно через , тому будь-які послідовних чисел з відрізка містять рівно одне з чисел 20, 40, 60, 80, 100. Якщо фігура — квадрат зі стороною , то і його діапазон рядків, і діапазон стовпців містять по такому числу, отже відповідна точка сітки гарантовано лежить усередині.

Тому якщо жоден із запитів не потрапив усередину, то хоча б одна сторона фігури менша за . Але тоді це точно не квадрат (інакше площа була б меншою за ) — одразу відповідаємо rectangle.

Крок 2: знайти лівий верхній кут. Нехай перша (у порядку обходу: спочатку за зростанням , потім за зростанням ) точка-влучання — це . Тоді x_1 \ge a - 19: інакше точка (a - 20, b) теж була б усередині, а вона йде раніше в порядку обходу.

Отже, x_1 шукаємо двійковим пошуком на відрізку [a-19,\, a]: предикат « всередині» монотонний, бо для x \le a точка всередині тоді й лише тоді, коли x \ge x_1. Аналогічно знаходимо y_1 на відрізку [b-19,\, b], запитуючи точки .

Крок 3: знайти меншу сторону. Ідемо по діагоналі з кута: точка (x_1 + m,\; y_1 + m) лежить усередині тоді й лише тоді, коли m \le x_2 - x_1 і m \le y_2 - y_1. Предикат знову монотонний, тому двійковим пошуком знаходимо найбільше таке ; позначимо його . За побудовою

d = \min(x_2 - x_1,\; y_2 - y_1).

Крок 4: відповідь. Фігура є квадратом тоді й лише тоді, коли обидві сторони дорівнюють , тобто коли жоден із двох «сусідів за кутом» не належить фігурі:

(x_1 + d + 1,\; y_1 + d) \quad \text{та} \quad (x_1 + d,\; y_1 + d + 1)

— обидві точки мають бути outside. Якщо хоч одна всередині, відповідна сторона довша, і це прямокутник.

Разом виходить близько 25 + 5 + 5 + 7 + 2 \approx 44 запити — з величезним запасом до ліміту .

Не забувайте робити flush після кожного запиту, інакше програма зависне в очікуванні відповіді.