Розділимо множину точок з цілими координатами на п'ять частин, як показано на рисунку: одна точка знаходиться в центрі, а решта чотири частини симетричні між собою і покривають чотири чверті кола. Якщо кількість точок, що лежать в одній з чвертей, дорівнює , то загальна кількість точок в колі буде 4 \cdot res + 1.
Обчислимо значення . Нехай радіус кола дорівнює . Переберемо значення від до . Тоді на прямій y = k~(0 \le k \le r) усередині кола опиниться \left\lfloor {\sqrt{r^2 - k^2}}\right\rfloor точок з цілими координатами. Загальна кількість таких точок на усіх рівнях і буде значенням :
Позначимо через загальну кількість цілих точок усередині кола радіуса . Тоді:
Функція f монотонно зростає. Завдання полягає в тому, щоб знайти мінімальне значення , для якого виконується рівність f(r) = n. Радіус лампи будемо шукати за допомогою бінарного пошуку.
Реалізація алгоритму
Функція count повертає кількість точок з цілими координатами, розташованих усередині кола радіуса .
long long count(long long r)
{
long long res = 0;
double r2 = r * r;
for (long long y = 0; y <= r; y++)
res += (long long)sqrt(r2 - y*y);
return 4 * res + 1;
}Основна частина програми. Читаємо вхідне значення .
scanf("%lld",&n);Радіус кола, який покриває щонайменше точок, шукаємо за допомогою бінарного пошуку. Спочатку припускаємо, що шуканий радіус знаходиться в діапазоні [l; r] = [0; 1000000].
l = 0; r = 1000000;
while (l < r)
{
m = (l + r ) / 2;Якщо кількість точок в колі радіуса менша , збільшуємо ліву границю інтервалу до m + 1 — радіуса недостатньо для покриття точок. В іншому випадку зменшуємо праву границю.
if (count (m) < n) l = m + 1; else r = m;
}Виводимо відповідь.
printf("%d\n",l);