На вход принимается радиус(целое число). Нужно вычислить сколько точек входит в круг. Пример:
В данном случае радиус равен 2. В круг с таким радиусом входит 13 точек
Формула окружности известна: x*x + y*y = r
.
Соответственно, если расстояние от точки до центра окружности равно радиусу или меньше, то данная точка лежит в круге:
Псевдокод (по умолчанию центр окружности лежит в 0,0. Если нет, то нужно это отдельно учесть):
bool checkInCircle(x, y, r){
if (math.sqrt(x**2 + y**2) <= r ){
return True;
}
}
Или, допустим, что точка - отдельный класс:
bool checkInCircle(point pt, int r){
if (math.sqrt(pt.x**2 + pt.y**2) <= r ){
return True;
}
}
Как я понимаю, точки - строго с целочисленными координатами. Если так, то тупо (даю схему)
count = 0
for i = -r to r
count = count + sqrt(r*r-i*i) * 2 + 1
next i
Под sqrt
имеется в виду целочисленное извлечение квадратного корня, с округлением вниз.
Само собой, всё это оптимизируется (можно считать только от 0 до r), но это уже мелочи.
Это задача Гаусса о количестве целочисленных точек в круге радиусом R с центром в начале координат. Явная формула неизвестна, только через сумму ряда
N(r) = 1 + 4 * Floor(r) + 4 * Sum({i=1..Floor(r)}:[Floor(Sqrt(r^2-i^2))])
Edit: по сути, Akina считает тем же методом
Разумный баланс между эффективностью и компактностью буквального алгоритма - это подход из ответа @Akina. Разумеется, имеет смысл использовать такой подход для подсчета точек только в половине круга, а далее аккуратно умножить результат на 2. (Аккуратно - значит помня о том, чтобы не посчитать пограничные точки дважды).
Однако и в буквальном алгоритме можно обойтись без тяжелых/нецелочисленных операций вроде вычисления квадратного корня, если генерировать ограничивающую окружность алгоритмом типа Брезенхэма-Мичнера.
Например, вот такое решение (сорри, на С) пользуется алгоритмом Мичнера для подсчета точек в одной четвертинке и последующего аккуратного (см. выше) умножения результата на 4. При этом для подсчета точек в четвертинке достаточно генерации лишь одной осьмушки дуги окружности (количество итераций цикла в коде ниже соответствует одной осьмушке окружности)
unsigned MichenerCircleCounter(int radius)
{
int radius2 = radius * radius;
int x = radius, y = 0;
int d = 1 - radius;
unsigned count = 0;
while (x >= y)
{
bool is_inside = x * x + y * y <= radius2;
unsigned add = (x - y + is_inside) * 2;
if (add > 0)
count += add - 1;
d += d <= 0 ? 2 * ++y + 1 : 2 * (++y - --x) + 1;
}
return (count - radius - 1) * 4 + 1;
}
Также по ссылке https://oeis.org/A057655 можно увидеть менее "буквальное" решение Гаусса
A(n) = 1 + 4 * ([n/1] - [n/3] + [n/5] - [n/7] + ...)
где n
- это квадрат радиуса круга
unsigned GaussCircleCounter(unsigned radius)
{
radius *= radius;
unsigned count = 0;
for (unsigned divisor = 1; divisor <= radius; divisor += 4)
{
count += radius / divisor;
count -= radius / (divisor + 2);
}
return count * 4 + 1;
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Всем приветЕсть 4 картинки с разными схемами автомобиля как во вложении
Проблема - несколько окружений, надо протестировать функционал, для прогона теста требуется userIdПользователь один и тот же, но на тесте у него...