LC - Maximum Number of Darts Inside of a Circular Dartboard

Author: Mihnea Brebenel

Table of Contents

ExplanationImplementation

Explanation

The general idea is the following: we can try finding the answer by placing the circle's boundary on each point, then sweep - or rotate - the circle around the point to see the maximum number of points that can be inside the circle. The picture below depicts how the sweep works:

angular-sweep

The sweeping around point pp can be done in O(NlogN)\mathcal{O}(N \cdot \log{N}) by computing for each point the angle of entering and exiting the circle. Afterward traverse the sorted array of angles while keeping track of active points i.e. points lying inside the circle. The considered angles will be relative to the center of the circle. Let's analyze how to find the entrace angle for a point:

angular-sweep

OO - circle's center; QQ - arbitrary point included in the list of points; rr - radius of circle; a,b,αa, b, \alpha - angles

We'll express the values of the angles in radians. The angle of entering the circle in this case is α\alpha which can be expressed as: α=ba\alpha = b - a. Angle aa is right above the x-axis so it's just arctg\arctg. Consider that b=QPOb=\angle{QPO} is an angle in the right triangle QPL\triangle QPL, where LL is the dimetral opposite point of PP on the circle, therefore PQL=90°\angle{PQL}=90\degree. In this case, knowing that PL=2rPL=2 \cdot r - diameter - and PQ=dist(P,Q)PQ=\texttt{dist}(P,Q), the angle BB can be conveniently expressed as arccos\arccos. Consequently, the angles a,ba, b have the following formulas:

a=arctgQyPyQxPxb=arccosdist(P,Q)2ra=\arctg{\frac{Q_y-P_y}{Q_x-P_x}}\\ b=\arccos{\frac{\texttt{dist}(P,Q)}{2 \cdot r}}

Now that we know how to find the entrance angle, it'll be easier to find the exit angle. With the same notations as the previous one - a,ba, b having the same formulas - consider this:

angular-sweep-exit

OO - circle's center; QQ - arbitrary point included in the list of points; rr - radius of circle; a,b,αa, b, \alpha - angles

It can be observed that: β=a+b\beta = a + b.

This algorithm is known as angular sweep or disk partial covering problem.

Implementation

Time Complexity: O(N2logN)\mathcal{O}(N^2 \cdot \log{N})

C++

class Solution {
public:
int numPoints(vector<vector<int>> &darts, int r) {
vector<vector<double>> dist(darts.size(), vector<double>(darts.size()));
// Compute the distance between points
for (int i = 0; i < darts.size(); i++) {
for (int j = i + 1; j < darts.size(); j++) {
int dx = darts[i][0] - darts[j][0];
int dy = darts[i][1] - darts[j][1];
dist[i][j] = dist[j][i] = sqrt(dx * dx + dy * dy);

Python

class Solution:
def numPoints(self, darts: List[List[int]], r: int) -> int:
# Compute the distances between all pairs of points
dist = [[0] * len(darts) for _ in range(len(darts))]
for i in range(len(darts)):
for j in range(i + 1, len(darts)):
dx = darts[i][0] - darts[j][0]
dy = darts[i][1] - darts[j][1]
dist[i][j] = dist[j][i] = math.sqrt(dx * dx + dy * dy)

Join the USACO Forum!

Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!