LC - Maximum Number of Darts Inside of a Circular Dartboard
Author: Mihnea Brebenel
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:
The sweeping around point can be done in 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:
We'll express the values of the angles in radians. The angle of entering the circle in this case is which can be expressed as: . Angle is right above the x-axis so it's just . Consider that is an angle in the right triangle , where is the dimetral opposite point of on the circle, therefore . In this case, knowing that - diameter - and , the angle can be conveniently expressed as . Consequently, the angles have the following formulas:
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 - having the same formulas - consider this:
It can be observed that: .
This algorithm is known as angular sweep or disk partial covering problem.
Implementation
Time Complexity:
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 pointsfor (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 pointsdist = [[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!