Нехай Смішарик знаходиться в точці . Тоді за секунд він зможе опинитися в будь-якій цілочисельній точці ромбу, як показано на рисунку.
Потрібно знайти найменше натуральне , при якому всі ромби відповідного розміру для кожного Смішарика матимуть хоча б одну спільну цілочисельну точку. Розглянемо третій тест і зобразимо ромби для трьох Смішариків при t = 1, 2, 3.
При t = 3 смішарики, наприклад, можуть зустрітися в точці або .
Обертаймо систему координат на відносно початку координат. При такому перетворенні ромби перетворяться у квадрати. Виведемо формули обертання:
Або в декартових координатах:
Позбудемося ірраціональності, розтягнувши зображення в \sqrt{2} рази. Для цього скористаємося наступним перетворенням:
Преобразуємо наші три точки:
(0, 0) → (0, 0)
(0, 3) → (3, 3)
(3, 3) → (6, 0)
Знайдемо координати прямокутника, що містить усі точки (x_i', y_i') — перетворені початкові координати смішариків. Позначимо:
min_x = min (x_i'); max_x = max (x_i');
min_y = min (y_i'); max_y = max (y_i');
Тоді прямокутник з протилежними кутами (min_x, min_y) та (max_x, max_y) містить усі точки (x_i', y_i'). При цьому він є мінімальним за площею прямокутником, сторони якого паралельні осям координат.
У нашому прикладі таким прямокутником буде (0, 0) - (6, 3).
Точкою збору смішариків (res_x, res_y) буде центр цього прямокутника, тобто точка з координатами
Тепер потрібно знайти мінімальний час, за який усі Смішарики зможуть дістатися з їхніх точок (x_i', y_i') до точки (res_x, res_y). Для повернутого ромба (квадрата в новій системі координат) відстань від точки (x_i', y_i') до (res_x, res_y) обчислюється за формулою:
Таким чином, усі Смішарики зможуть зібратися в точці (res_x, res_y) за час, рівний максимальному з цих відстаней:
Реалізація алгоритму
Оголосимо константу нескінченність .
typedef long long ll;
#define INFL (ll)4e18Вхідні точки будемо зберігати в масиві .
vector<pair<ll, ll>> inp;Функція calc обчислює відстань від точки до найвіддаленішого Смішарика. Перетворені координати Смішариків знаходяться в масиві .
ll calc(ll x, ll y)
{
ll res = 0;
for (auto p : inp)
res = max(res, max(abs(p.first - x), abs(p.second - y)));
return res;
}Основна частина програми. Читаємо вхідні дані.
cin >> n;
minx = INFL; maxx = -INFL; miny = INFL; maxy = -INFL;
for (i = 0; i < n; i++)
{Читаємо вихідні координати Смішарика . Виконуємо поворот координатної площини на і зберігаємо отримані координати в масиві .
cin >> x >> y;
nx = x + y;
ny = -x + y;
inp.push_back({ nx, ny });Після цього знаходимо координати прямокутника з протилежними кутами (min_x, min_y) і (max_x, max_y), який містить усі точки (x_i', y_i') — перетворені координати Смішариків.
minx = min(minx, nx);
maxx = max(maxx, nx);
miny = min(miny, ny);
maxy = max(maxy, ny);
}Визначаємо точку збору Смішариків (res_x, res_y) — центр прямокутника.
resx = (minx + maxx) / 2;
resy = (miny + maxy) / 2;Обчислюємо і виводимо мінімальний час, необхідний для того, щоб усі Смішарики змогли дістатися з їхніх точок (x_i', y_i') до точки (res_x, res_y).
ans = calc(resx, resy);
cout << ans << "\n";