Open In App
Related Articles

Minimum time at which at least K out of N circles expanding 1 unit per second overlap

Improve Article
Improve
Save Article
Save
Like Article
Like

Given N points on a 2D infinite plane, where each point represents the center of a circle initially having a radius of 0 which expands at a constant rate of 1 unit per second, the task is to find the minimum time at which at least K circles overlap at a point.

Example: 

Input: points[] = {{8, 5}, {0, 4}, {3, 6}}, K = 3
Output:
Explanation: Consider infinite grid as shown in the image below. the image shows the state of the circles after 5 seconds. Each of the three circles overlap and all the points in the yellow highlighted region has at least 3 overlapping circles. Therefore, after 5 seconds, there exists a point on the plane (i.e, (5, 4)) such that at least 3 circles overlap it and it is the minimum possible time.

Input: points[] = {{0, 0}, {1, 1}, {2, 2}}, K = 2
Output:

 

Approach: The given problem 

C++




// C++ implementation of the above approach
#include <bits/stdc++.h>
using namespace std;
 
struct coord {
    long double x, y;
};
 
// Function to find the square of the
// distance between  two given points
long double distance(coord a, coord b)
{
    // Distance Formulae
    return (a.x - b.x) * (a.x - b.x)
           + (a.y - b.y) * (a.y - b.y);
}
 
// Function to check if there exist a
// point having K overlapping circles with
// the radius of each circle as mid
bool check(vector<coord> points, int k,
           long double mid)
{
    // Squaring the value of mid
    // for simplicity of calculation
    mid *= mid;
    for (int i = 0; i < points.size(); i++) {
        for (int j = i + 1; j < points.size(); j++) {
 
            // Stores the coordinates
            // of 1st circle
            coord C1 = points[i];
 
            // Stores the coordinates
            // of 2nd circle
            coord C2 = points[j];
 
            // Calculating dist and h
            // as discussed in approach
            long double dist = distance(C1, C2);
            long double h
                = sqrt((4 * mid - dist)
                       / dist);
 
            // If Circles do not intersect
            if (dist > 4 * mid)
                continue;
 
            // Stores two intersection points
            coord P1, P2;
 
            // By help of formulaes given above
            P1.x = ((C1.x + C2.x)
                    + h * (C1.y - C2.y))
                   / 2;
            P1.y = ((C1.y + C2.y)
                    + h * (C2.x - C1.x))
                   / 2;
            P2.x = ((C1.x + C2.x)
                    - h * (C1.y - C2.y))
                   / 2;
            P2.y = ((C1.y + C2.y)
                    + h * (C2.x - C1.x))
                   / 2;
 
            // Stores count of overlapping
            // circles over P1 and P2
            int cnt1 = 0, cnt2 = 0;
 
            // Loop to traverse over all the circles
            for (int k = 0; k < points.size(); k++) {
 
                // If P1 lies inside Kth circle
                if (distance(P1, points[k]) - mid
                    <= 0.000001)
                    cnt1++;
 
                // If P2 lies inside Kth circle
                if (distance(P2, points[k]) - mid
                    <= 0.000001)
                    cnt2++;
            }
 
            // If count of overlapping circles
            // is more than K
            if (cnt1 >= k || cnt2 >= k) {
                return true;
            }
        }
    }
 
    // If no valid point is found
    return false;
}
 
// Function to perform the binary
// search over the radius of the
// circles in the range [0, ∞]
int binSearchOnRad(vector<coord>& points, int k)
{
    // Stores the start and end of
    // range of the binary search
    int start = 0, end = 1e6;
 
    // Loop to perform binary search
    while (start <= end) {
 
        // Stores the mid if the
        // current range
        int mid = start + (end - start) / 2;
 
        // If there exist a point having
        // k overlapping circles with the
        // radius of circles as mid
        if (check(points, k, mid)) {
            end = mid - 1;
        }
 
        // If the required point
        // does not exist
        else {
            start = mid + 1;
        }
    }
 
    // Return Answer
    return start;
}
 
// Driver Code
int main()
{
    vector<coord> points = { { 8, 5 },
                             { 0, 4 },
                             { 3, 6 } };
    int K = 3;
 
    cout << binSearchOnRad(points, K);
 
    return 0;
}


Java




// Java implementation for the above approach
import java.io.*;
 
class GFG{
 
// Function to find the square of the
// distance between  two given points
static double distance(double[] a, double[] b)
{
     
    // Distance Formulae
    return (a[0] - b[0]) * (a[0] - b[0]) +
           (a[1] - b[1]) * (a[1] - b[1]);
}
 
// Function to check if there exist a
// point having K overlapping circles with
// the radius of each circle as mid
static boolean check(double[][] points, int k,
                     double mid)
{
     
    // Squaring the value of mid
    // for simplicity of calculation
    mid *= mid;
    for(int i = 0; i < points.length; i++)
    {
        for(int j = i + 1; j < points.length; j++)
        {
             
            // Stores the coordinates
            // of 1st circle
            double[] C1 = points[i];
 
            // Stores the coordinates
            // of 2nd circle
            double[] C2 = points[j];
 
            // Calculating dist and h
            // as discussed in approach
            double dist = distance(C1, C2);
            double h = Math.sqrt((4 * mid - dist) / dist);
 
            // If Circles do not intersect
            if (dist > 4 * mid)
                continue;
 
            // Stores two intersection points
            double[] P1 = new double[2];
            double[] P2 = new double[2];
 
            // By help of formulaes given above
            P1[0] = ((C1[0] + C2[0]) +
                 h * (C1[1] - C2[1])) / 2;
            P1[1] = ((C1[1] + C2[1]) +
                 h * (C2[0] - C1[0])) / 2;
            P2[0] = ((C1[0] + C2[0]) -
                 h * (C1[1] - C2[1])) / 2;
            P2[1] = ((C1[1] + C2[1]) +
                 h * (C2[0] - C1[0])) / 2;
 
            // Stores count of overlapping
            // circles over P1 and P2
            int cnt1 = 0;
            int cnt2 = 0;
 
            // Loop to traverse over all the circles
            for(k = 0; k < points.length; k++)
            {
                 
                // If P1 lies inside Kth circle
                if (distance(P1, points[k]) - mid <= 0.000001)
                    cnt1++;
 
                // If P2 lies inside Kth circle
                if (distance(P2, points[k]) - mid <= 0.000001)
                    cnt2++;
            }
 
            // If count of overlapping circles
            // is more than K
            if (cnt1 >= k || cnt2 >= k)
            {
                return true;
            }
        }
    }
 
    // If no valid point is found
    return false;
}
 
// Function to perform the binary
// search over the radius of the
// circles in the range [0, ∞]
static int binSearchOnRad(double[][] points, int k)
{
     
    // Stores the start and end of
    // range of the binary search
    int start = 0, end = (int)1e6;
 
    // Loop to perform binary search
    while (start <= end)
    {
         
        // Stores the mid if the
        // current range
        int mid = start + (end - start) / 2;
 
        // If there exist a point having
        // k overlapping circles with the
        // radius of circles as mid
        if (check(points, k, mid))
        {
            end = mid - 1;
        }
 
        // If the required point
        // does not exist
        else
        {
            start = mid + 1;
        }
    }
 
    // Return Answer
    return start;
}
 
// Driver Code
public static void main(String[] args)
{
    double[][] points = { { 8, 5 }, { 0, 4 }, { 3, 6 } };
    int K = 3;
 
    System.out.println(binSearchOnRad(points, K));
}
}
 
// This code is contributed by Potta Lokesh


Python3




# Python implementation of the above approach
 
# Function to find the square of the
# distance between two given points
def distance(a, b):
 
    # Distance Formulae
    return (a[0] - b[0]) * (a[0] - b[0]) + (a[1] - b[1]) * (a[1] - b[1])
 
# Function to check if there exist a
# point having K overlapping circles with
# the radius of each circle as mid
def check(points, k, mid):
 
    # Squaring the value of mid
    # for simplicity of calculation
    mid *= mid
    for i in range(len(points)):
        for j in range(i + 1, len(points)):
 
            # Stores the coordinates
            # of 1st circle
            C1 = points[i]
 
            # Stores the coordinates
            # of 2nd circle
            C2 = points[j]
 
            # Calculating dist and h
            # as discussed in approach
            dist = distance(C1, C2)
            h = ((4 * mid - dist) / dist) ** (1 / 2)
 
            # If Circles do not intersect
            if (dist > 4 * mid):
                continue
 
            # Stores two intersection points
            P1 = [0] * 2
            P2 = [0] * 2
 
            # By help of formulaes given above
            P1[0] = ((C1[0] + C2[0]) +
                     h * (C1[1] - C2[1])) // 2
            P1[1] = ((C1[1] + C2[1]) +
                     h * (C2[0] - C1[0])) // 2
            P2[0] = ((C1[0] + C2[0]) -
                     h * (C1[1] - C2[1])) // 2
            P2[1] = ((C1[1] + C2[1]) +
                     h * (C2[0] - C1[0])) // 2
 
            # Stores count of overlapping
            # circles over P1 and P2
            cnt1 = 0
            cnt2 = 0
 
            # Loop to traverse over all the circles
            for k in range(len(points)):
 
                # If P1 lies inside Kth circle
                if (distance(P1, points[k]) - mid <= 0.000001):
                    cnt1 += 1
 
                # If P2 lies inside Kth circle
                if (distance(P2, points[k]) - mid <= 0.000001):
                    cnt2 += 1
 
            # If count of overlapping circles
            # is more than K
            if (cnt1 >= k or cnt2 >= k):
                return True
 
    # If no valid point is found
    return False
 
 
# Function to perform the binary
# search over the radius of the
# circles in the range [0, ∞]
def binSearchOnRad(points, k):
 
    # Stores the start and end of
    # range of the binary search
    start = 0
    end = 1000000
 
    # Loop to perform binary search
    while (start <= end):
 
        # Stores the mid if the
        # current range
        mid = start + (end - start) // 2
 
        # If there exist a point having
        # k overlapping circles with the
        # radius of circles as mid
        if (check(points, k, mid)):
            end = mid - 1
 
        # If the required point
        # does not exist
        else:
            start = mid + 1
 
    # Return Answer
    return start
 
# Driver Code
points = [[8, 5], [0, 4], [3, 6]]
K = 3
 
print(binSearchOnRad(points, K))
 
# This code is contributed by Saurabh Jaiswal


C#




// C# implementation for the above approach
using System;
class GFG {
 
  // Function to find the square of the
  // distance between  two given points
  static double distance(double[] a, double[] b)
  {
 
    // Distance Formulae
    return (a[0] - b[0]) * (a[0] - b[0])
      + (a[1] - b[1]) * (a[1] - b[1]);
  }
 
  // Function to check if there exist a
  // point having K overlapping circles with
  // the radius of each circle as mid
  static bool check(double[, ] points, int k, double mid)
  {
 
    // Squaring the value of mid
    // for simplicity of calculation
    mid *= mid;
    for (int i = 0; i < points.GetLength(0); i++) {
      for (int j = i + 1; j < points.GetLength(0);
           j++) {
 
        // Stores the coordinates
        // of 1st circle
        double[] C1
          = new double[points.GetLength(1)];
        for (int x = 0; x < points.GetLength(1);
             x++)
          C1[x] = points[i, x];
 
        // Stores the coordinates
        // of 2nd circle
        double[] C2
          = new double[points.GetLength(1)];
        for (int x = 0; x < points.GetLength(1);
             x++)
          C2[x] = points[j, x];
 
        // Calculating dist and h
        // as discussed in approach
        double dist = distance(C1, C2);
        double h
          = Math.Sqrt((4 * mid - dist) / dist);
 
        // If Circles do not intersect
        if (dist > 4 * mid)
          continue;
 
        // Stores two intersection points
        double[] P1 = new double[2];
        double[] P2 = new double[2];
 
        // By help of formulaes given above
        P1[0] = ((C1[0] + C2[0])
                 + h * (C1[1] - C2[1]))
          / 2;
        P1[1] = ((C1[1] + C2[1])
                 + h * (C2[0] - C1[0]))
          / 2;
        P2[0] = ((C1[0] + C2[0])
                 - h * (C1[1] - C2[1]))
          / 2;
        P2[1] = ((C1[1] + C2[1])
                 + h * (C2[0] - C1[0]))
          / 2;
 
        // Stores count of overlapping
        // circles over P1 and P2
        int cnt1 = 0;
        int cnt2 = 0;
 
        // Loop to traverse over all the circles
        for (k = 0; k < points.GetLength(0); k++) {
          double[] P
            = new double[points.GetLength(1)];
          for (int x = 0; x < points.GetLength(1);
               x++)
            P[x] = points[k, x];
          // If P1 lies inside Kth circle
          if (distance(P1, P) - mid <= 0.000001)
            cnt1++;
 
          // If P2 lies inside Kth circle
          if (distance(P2, P) - mid <= 0.000001)
            cnt2++;
        }
 
        // If count of overlapping circles
        // is more than K
        if (cnt1 >= k || cnt2 >= k) {
          return true;
        }
      }
    }
 
    // If no valid point is found
    return false;
  }
 
  // Function to perform the binary
  // search over the radius of the
  // circles in the range [0, ∞]
  static int binSearchOnRad(double[, ] points, int k)
  {
 
    // Stores the start and end of
    // range of the binary search
    int start = 0, end = (int)1e6;
 
    // Loop to perform binary search
    while (start <= end) {
 
      // Stores the mid if the
      // current range
      int mid = start + (end - start) / 2;
 
      // If there exist a point having
      // k overlapping circles with the
      // radius of circles as mid
      if (check(points, k, mid)) {
        end = mid - 1;
      }
 
      // If the required point
      // does not exist
      else {
        start = mid + 1;
      }
    }
 
    // Return Answer
    return start;
  }
 
  // Driver Code
  public static void Main(string[] args)
  {
    double[, ] points
      = { { 8, 5 }, { 0, 4 }, { 3, 6 } };
    int K = 3;
 
    Console.WriteLine(binSearchOnRad(points, K));
  }
}
 
// This code is contributed by ukasp.


Javascript




<script>
 
// JavaScript implementation of the above approach
 
// Function to find the square of the
// distance between two given points
const distance = (a, b) =>
{
     
    // Distance Formulae
    return (a[0] - b[0]) * (a[0] - b[0]) +
           (a[1] - b[1]) * (a[1] - b[1]);
}
 
// Function to check if there exist a
// point having K overlapping circles with
// the radius of each circle as mid
const check = (points, k, mid) =>
{
     
    // Squaring the value of mid
    // for simplicity of calculation
    mid *= mid;
    for(let i = 0; i < points.length; i++)
    {
        for(let j = i + 1; j < points.length; j++)
        {
             
            // Stores the coordinates
            // of 1st circle
            let C1 = points[i];
 
            // Stores the coordinates
            // of 2nd circle
            let C2 = points[j];
 
            // Calculating dist and h
            // as discussed in approach
            let dist = distance(C1, C2);
            let h = Math.sqrt((4 * mid - dist) / dist);
 
            // If Circles do not intersect
            if (dist > 4 * mid)
                continue;
 
            // Stores two intersection points
            let P1 = new Array(2).fill(0),
                P2 = new Array(2).fill(0);
 
            // By help of formulaes given above
            P1[0] = ((C1[0] + C2[0]) +
                 h * (C1[1] - C2[1])) / 2;
            P1[1] = ((C1[1] + C2[1]) +
                 h * (C2[0] - C1[0])) / 2;
            P2.x = ((C1[0] + C2[0]) -
                h * (C1[1] - C2[1])) / 2;
            P2.y = ((C1[1] + C2[1]) +
                h * (C2[0] - C1[0])) / 2;
 
            // Stores count of overlapping
            // circles over P1 and P2
            let cnt1 = 0, cnt2 = 0;
 
            // Loop to traverse over all the circles
            for(let k = 0; k < points.length; k++)
            {
                 
                // If P1 lies inside Kth circle
                if (distance(P1, points[k]) - mid <= 0.000001)
                    cnt1++;
 
                // If P2 lies inside Kth circle
                if (distance(P2, points[k]) - mid <= 0.000001)
                    cnt2++;
            }
 
            // If count of overlapping circles
            // is more than K
            if (cnt1 >= k || cnt2 >= k)
            {
                return true;
            }
        }
    }
 
    // If no valid point is found
    return false;
}
 
// Function to perform the binary
// search over the radius of the
// circles in the range [0, ∞]
const binSearchOnRad = (points, k) =>
{
     
    // Stores the start and end of
    // range of the binary search
    let start = 0, end = 1000000;
 
    // Loop to perform binary search
    while (start <= end)
    {
         
        // Stores the mid if the
        // current range
        let mid = start + parseInt((end - start) / 2);
 
        // If there exist a point having
        // k overlapping circles with the
        // radius of circles as mid
        if (check(points, k, mid))
        {
            end = mid - 1;
        }
 
        // If the required point
        // does not exist
        else
        {
            start = mid + 1;
        }
    }
 
    // Return Answer
    return start;
}
 
// Driver Code
let points = [ [ 8, 5 ], [ 0, 4 ], [ 3, 6 ] ];
let K = 3;
 
document.write(binSearchOnRad(points, K));
 
// This code is contributed by rakeshsahni
 
</script>


can be solved with the help of the binary search using the following observations: 

  • At any given time t, the radius of all the circles must be t. Therefore, the problem can be converted into finding the smallest radius such that at least K circles overlap at a given point.
  • The smallest required radius can be calculated by performing a binary search over it in the range [0, ∞].

Now, the required task is to check for a given radius r, if the count of overlapping circles of radius r at any point is more than or equal to K. It can be done using the following technique:

  • The task is to calculate the value of P1 and P2 which can be done by the following procedure:

dist = √( (x1 – x2)2 + (y1 – y2)2)  [Using the distance formula]
h = √((mid)2 – (dist/2)2)  [Using the Pythagorean theorem]

Using the values of dist and h, P1 and P2 can be calculated by the following formulae:
=> P1 = ( ((x1 + x2) + h * ( y1 – y2 )) / 2, ((y1 + y2) + h * ( x2 – x1 )) / 2) and similarly 
=> P2 = ( ((x1 + x2) – h * ( y1 – y2 )) / 2, ((y1+ y2) – h * ( x2 – x1 )) / 2)

Therefore, for all possible pairs of intersecting circles, calculate the value of P1 and P2 and calculate the count of circles such that P1 lies in that circles in a variable cnt1 and similarly calculate the count of circles such that P2 lies in that circle in a variable cnt2. If any of the values of cnt1 and cnt2 is greater than K, it means for the given r = mid, there exists a point in the plane such that at least K circles overlap over it.

Below is the implementation of the above approach:

C++




// C++ implementation of the above approach
#include <bits/stdc++.h>
using namespace std;
 
struct coord {
    long double x, y;
};
 
// Function to find the square of the
// distance between  two given points
long double distance(coord a, coord b)
{
    // Distance Formulae
    return (a.x - b.x) * (a.x - b.x)
           + (a.y - b.y) * (a.y - b.y);
}
 
// Function to check if there exist a
// point having K overlapping circles with
// the radius of each circle as mid
bool check(vector<coord> points, int k,
           long double mid)
{
    // Squaring the value of mid
    // for simplicity of calculation
    mid *= mid;
    for (int i = 0; i < points.size(); i++) {
        for (int j = i + 1; j < points.size(); j++) {
 
            // Stores the coordinates
            // of 1st circle
            coord C1 = points[i];
 
            // Stores the coordinates
            // of 2nd circle
            coord C2 = points[j];
 
            // Calculating dist and h
            // as discussed in approach
            long double dist = distance(C1, C2);
            long double h
                = sqrt((4 * mid - dist)
                       / dist);
 
            // If Circles do not intersect
            if (dist > 4 * mid)
                continue;
 
            // Stores two intersection points
            coord P1, P2;
 
            // By help of formulaes given above
            P1.x = ((C1.x + C2.x)
                    + h * (C1.y - C2.y))
                   / 2;
            P1.y = ((C1.y + C2.y)
                    + h * (C2.x - C1.x))
                   / 2;
            P2.x = ((C1.x + C2.x)
                    - h * (C1.y - C2.y))
                   / 2;
            P2.y = ((C1.y + C2.y)
                    + h * (C2.x - C1.x))
                   / 2;
 
            // Stores count of overlapping
            // circles over P1 and P2
            int cnt1 = 0, cnt2 = 0;
 
            // Loop to traverse over all the circles
            for (int k = 0; k < points.size(); k++) {
 
                // If P1 lies inside Kth circle
                if (distance(P1, points[k]) - mid
                    <= 0.000001)
                    cnt1++;
 
                // If P2 lies inside Kth circle
                if (distance(P2, points[k]) - mid
                    <= 0.000001)
                    cnt2++;
            }
 
            // If count of overlapping circles
            // is more than K
            if (cnt1 >= k || cnt2 >= k) {
                return true;
            }
        }
    }
 
    // If no valid point is found
    return false;
}
 
// Function to perform the binary
// search over the radius of the
// circles in the range [0, ∞]
int binSearchOnRad(vector<coord>& points, int k)
{
    // Stores the start and end of
    // range of the binary search
    int start = 0, end = 1e6;
 
    // Loop to perform binary search
    while (start <= end) {
 
        // Stores the mid if the
        // current range
        int mid = start + (end - start) / 2;
 
        // If there exist a point having
        // k overlapping circles with the
        // radius of circles as mid
        if (check(points, k, mid)) {
            end = mid - 1;
        }
 
        // If the required point
        // does not exist
        else {
            start = mid + 1;
        }
    }
 
    // Return Answer
    return start;
}
 
// Driver Code
int main()
{
    vector<coord> points = { { 8, 5 },
                             { 0, 4 },
                             { 3, 6 } };
    int K = 3;
 
    cout << binSearchOnRad(points, K);
 
    return 0;
}


Java




// Java implementation for the above approach
import java.io.*;
 
class GFG{
 
// Function to find the square of the
// distance between  two given points
static double distance(double[] a, double[] b)
{
     
    // Distance Formulae
    return (a[0] - b[0]) * (a[0] - b[0]) +
           (a[1] - b[1]) * (a[1] - b[1]);
}
 
// Function to check if there exist a
// point having K overlapping circles with
// the radius of each circle as mid
static boolean check(double[][] points, int k,
                     double mid)
{
     
    // Squaring the value of mid
    // for simplicity of calculation
    mid *= mid;
    for(int i = 0; i < points.length; i++)
    {
        for(int j = i + 1; j < points.length; j++)
        {
             
            // Stores the coordinates
            // of 1st circle
            double[] C1 = points[i];
 
            // Stores the coordinates
            // of 2nd circle
            double[] C2 = points[j];
 
            // Calculating dist and h
            // as discussed in approach
            double dist = distance(C1, C2);
            double h = Math.sqrt((4 * mid - dist) / dist);
 
            // If Circles do not intersect
            if (dist > 4 * mid)
                continue;
 
            // Stores two intersection points
            double[] P1 = new double[2];
            double[] P2 = new double[2];
 
            // By help of formulaes given above
            P1[0] = ((C1[0] + C2[0]) +
                 h * (C1[1] - C2[1])) / 2;
            P1[1] = ((C1[1] + C2[1]) +
                 h * (C2[0] - C1[0])) / 2;
            P2[0] = ((C1[0] + C2[0]) -
                 h * (C1[1] - C2[1])) / 2;
            P2[1] = ((C1[1] + C2[1]) +
                 h * (C2[0] - C1[0])) / 2;
 
            // Stores count of overlapping
            // circles over P1 and P2
            int cnt1 = 0;
            int cnt2 = 0;
 
            // Loop to traverse over all the circles
            for(k = 0; k < points.length; k++)
            {
                 
                // If P1 lies inside Kth circle
                if (distance(P1, points[k]) - mid <= 0.000001)
                    cnt1++;
 
                // If P2 lies inside Kth circle
                if (distance(P2, points[k]) - mid <= 0.000001)
                    cnt2++;
            }
 
            // If count of overlapping circles
            // is more than K
            if (cnt1 >= k || cnt2 >= k)
            {
                return true;
            }
        }
    }
 
    // If no valid point is found
    return false;
}
 
// Function to perform the binary
// search over the radius of the
// circles in the range [0, ∞]
static int binSearchOnRad(double[][] points, int k)
{
     
    // Stores the start and end of
    // range of the binary search
    int start = 0, end = (int)1e6;
 
    // Loop to perform binary search
    while (start <= end)
    {
         
        // Stores the mid if the
        // current range
        int mid = start + (end - start) / 2;
 
        // If there exist a point having
        // k overlapping circles with the
        // radius of circles as mid
        if (check(points, k, mid))
        {
            end = mid - 1;
        }
 
        // If the required point
        // does not exist
        else
        {
            start = mid + 1;
        }
    }
 
    // Return Answer
    return start;
}
 
// Driver Code
public static void main(String[] args)
{
    double[][] points = { { 8, 5 }, { 0, 4 }, { 3, 6 } };
    int K = 3;
 
    System.out.println(binSearchOnRad(points, K));
}
}
 
// This code is contributed by Potta Lokesh


Python3




# Python implementation of the above approach
 
# Function to find the square of the
# distance between two given points
def distance(a, b):
 
    # Distance Formulae
    return (a[0] - b[0]) * (a[0] - b[0]) + (a[1] - b[1]) * (a[1] - b[1])
 
# Function to check if there exist a
# point having K overlapping circles with
# the radius of each circle as mid
def check(points, k, mid):
 
    # Squaring the value of mid
    # for simplicity of calculation
    mid *= mid
    for i in range(len(points)):
        for j in range(i + 1, len(points)):
 
            # Stores the coordinates
            # of 1st circle
            C1 = points[i]
 
            # Stores the coordinates
            # of 2nd circle
            C2 = points[j]
 
            # Calculating dist and h
            # as discussed in approach
            dist = distance(C1, C2)
            h = ((4 * mid - dist) / dist) ** (1 / 2)
 
            # If Circles do not intersect
            if (dist > 4 * mid):
                continue
 
            # Stores two intersection points
            P1 = [0] * 2
            P2 = [0] * 2
 
            # By help of formulaes given above
            P1[0] = ((C1[0] + C2[0]) +
                     h * (C1[1] - C2[1])) // 2
            P1[1] = ((C1[1] + C2[1]) +
                     h * (C2[0] - C1[0])) // 2
            P2[0] = ((C1[0] + C2[0]) -
                     h * (C1[1] - C2[1])) // 2
            P2[1] = ((C1[1] + C2[1]) +
                     h * (C2[0] - C1[0])) // 2
 
            # Stores count of overlapping
            # circles over P1 and P2
            cnt1 = 0
            cnt2 = 0
 
            # Loop to traverse over all the circles
            for k in range(len(points)):
 
                # If P1 lies inside Kth circle
                if (distance(P1, points[k]) - mid <= 0.000001):
                    cnt1 += 1
 
                # If P2 lies inside Kth circle
                if (distance(P2, points[k]) - mid <= 0.000001):
                    cnt2 += 1
 
            # If count of overlapping circles
            # is more than K
            if (cnt1 >= k or cnt2 >= k):
                return True
 
    # If no valid point is found
    return False
 
 
# Function to perform the binary
# search over the radius of the
# circles in the range [0, ∞]
def binSearchOnRad(points, k):
 
    # Stores the start and end of
    # range of the binary search
    start = 0
    end = 1000000
 
    # Loop to perform binary search
    while (start <= end):
 
        # Stores the mid if the
        # current range
        mid = start + (end - start) // 2
 
        # If there exist a point having
        # k overlapping circles with the
        # radius of circles as mid
        if (check(points, k, mid)):
            end = mid - 1
 
        # If the required point
        # does not exist
        else:
            start = mid + 1
 
    # Return Answer
    return start
 
# Driver Code
points = [[8, 5], [0, 4], [3, 6]]
K = 3
 
print(binSearchOnRad(points, K))
 
# This code is contributed by Saurabh Jaiswal


C#




// C# implementation for the above approach
using System;
class GFG {
 
  // Function to find the square of the
  // distance between  two given points
  static double distance(double[] a, double[] b)
  {
 
    // Distance Formulae
    return (a[0] - b[0]) * (a[0] - b[0])
      + (a[1] - b[1]) * (a[1] - b[1]);
  }
 
  // Function to check if there exist a
  // point having K overlapping circles with
  // the radius of each circle as mid
  static bool check(double[, ] points, int k, double mid)
  {
 
    // Squaring the value of mid
    // for simplicity of calculation
    mid *= mid;
    for (int i = 0; i < points.GetLength(0); i++) {
      for (int j = i + 1; j < points.GetLength(0);
           j++) {
 
        // Stores the coordinates
        // of 1st circle
        double[] C1
          = new double[points.GetLength(1)];
        for (int x = 0; x < points.GetLength(1);
             x++)
          C1[x] = points[i, x];
 
        // Stores the coordinates
        // of 2nd circle
        double[] C2
          = new double[points.GetLength(1)];
        for (int x = 0; x < points.GetLength(1);
             x++)
          C2[x] = points[j, x];
 
        // Calculating dist and h
        // as discussed in approach
        double dist = distance(C1, C2);
        double h
          = Math.Sqrt((4 * mid - dist) / dist);
 
        // If Circles do not intersect
        if (dist > 4 * mid)
          continue;
 
        // Stores two intersection points
        double[] P1 = new double[2];
        double[] P2 = new double[2];
 
        // By help of formulaes given above
        P1[0] = ((C1[0] + C2[0])
                 + h * (C1[1] - C2[1]))
          / 2;
        P1[1] = ((C1[1] + C2[1])
                 + h * (C2[0] - C1[0]))
          / 2;
        P2[0] = ((C1[0] + C2[0])
                 - h * (C1[1] - C2[1]))
          / 2;
        P2[1] = ((C1[1] + C2[1])
                 + h * (C2[0] - C1[0]))
          / 2;
 
        // Stores count of overlapping
        // circles over P1 and P2
        int cnt1 = 0;
        int cnt2 = 0;
 
        // Loop to traverse over all the circles
        for (k = 0; k < points.GetLength(0); k++) {
          double[] P
            = new double[points.GetLength(1)];
          for (int x = 0; x < points.GetLength(1);
               x++)
            P[x] = points[k, x];
          // If P1 lies inside Kth circle
          if (distance(P1, P) - mid <= 0.000001)
            cnt1++;
 
          // If P2 lies inside Kth circle
          if (distance(P2, P) - mid <= 0.000001)
            cnt2++;
        }
 
        // If count of overlapping circles
        // is more than K
        if (cnt1 >= k || cnt2 >= k) {
          return true;
        }
      }
    }
 
    // If no valid point is found
    return false;
  }
 
  // Function to perform the binary
  // search over the radius of the
  // circles in the range [0, ∞]
  static int binSearchOnRad(double[, ] points, int k)
  {
 
    // Stores the start and end of
    // range of the binary search
    int start = 0, end = (int)1e6;
 
    // Loop to perform binary search
    while (start <= end) {
 
      // Stores the mid if the
      // current range
      int mid = start + (end - start) / 2;
 
      // If there exist a point having
      // k overlapping circles with the
      // radius of circles as mid
      if (check(points, k, mid)) {
        end = mid - 1;
      }
 
      // If the required point
      // does not exist
      else {
        start = mid + 1;
      }
    }
 
    // Return Answer
    return start;
  }
 
  // Driver Code
  public static void Main(string[] args)
  {
    double[, ] points
      = { { 8, 5 }, { 0, 4 }, { 3, 6 } };
    int K = 3;
 
    Console.WriteLine(binSearchOnRad(points, K));
  }
}
 
// This code is contributed by ukasp.


Javascript




<script>
 
// JavaScript implementation of the above approach
 
// Function to find the square of the
// distance between two given points
const distance = (a, b) =>
{
     
    // Distance Formulae
    return (a[0] - b[0]) * (a[0] - b[0]) +
           (a[1] - b[1]) * (a[1] - b[1]);
}
 
// Function to check if there exist a
// point having K overlapping circles with
// the radius of each circle as mid
const check = (points, k, mid) =>
{
     
    // Squaring the value of mid
    // for simplicity of calculation
    mid *= mid;
    for(let i = 0; i < points.length; i++)
    {
        for(let j = i + 1; j < points.length; j++)
        {
             
            // Stores the coordinates
            // of 1st circle
            let C1 = points[i];
 
            // Stores the coordinates
            // of 2nd circle
            let C2 = points[j];
 
            // Calculating dist and h
            // as discussed in approach
            let dist = distance(C1, C2);
            let h = Math.sqrt((4 * mid - dist) / dist);
 
            // If Circles do not intersect
            if (dist > 4 * mid)
                continue;
 
            // Stores two intersection points
            let P1 = new Array(2).fill(0),
                P2 = new Array(2).fill(0);
 
            // By help of formulaes given above
            P1[0] = ((C1[0] + C2[0]) +
                 h * (C1[1] - C2[1])) / 2;
            P1[1] = ((C1[1] + C2[1]) +
                 h * (C2[0] - C1[0])) / 2;
            P2.x = ((C1[0] + C2[0]) -
                h * (C1[1] - C2[1])) / 2;
            P2.y = ((C1[1] + C2[1]) +
                h * (C2[0] - C1[0])) / 2;
 
            // Stores count of overlapping
            // circles over P1 and P2
            let cnt1 = 0, cnt2 = 0;
 
            // Loop to traverse over all the circles
            for(let k = 0; k < points.length; k++)
            {
                 
                // If P1 lies inside Kth circle
                if (distance(P1, points[k]) - mid <= 0.000001)
                    cnt1++;
 
                // If P2 lies inside Kth circle
                if (distance(P2, points[k]) - mid <= 0.000001)
                    cnt2++;
            }
 
            // If count of overlapping circles
            // is more than K
            if (cnt1 >= k || cnt2 >= k)
            {
                return true;
            }
        }
    }
 
    // If no valid point is found
    return false;
}
 
// Function to perform the binary
// search over the radius of the
// circles in the range [0, ∞]
const binSearchOnRad = (points, k) =>
{
     
    // Stores the start and end of
    // range of the binary search
    let start = 0, end = 1000000;
 
    // Loop to perform binary search
    while (start <= end)
    {
         
        // Stores the mid if the
        // current range
        let mid = start + parseInt((end - start) / 2);
 
        // If there exist a point having
        // k overlapping circles with the
        // radius of circles as mid
        if (check(points, k, mid))
        {
            end = mid - 1;
        }
 
        // If the required point
        // does not exist
        else
        {
            start = mid + 1;
        }
    }
 
    // Return Answer
    return start;
}
 
// Driver Code
let points = [ [ 8, 5 ], [ 0, 4 ], [ 3, 6 ] ];
let K = 3;
 
document.write(binSearchOnRad(points, K));
 
// This code is contributed by rakeshsahni
 
</script>


Output

5

Time Complexity: O(N3 * log N)
Auxiliary Space: O(1)


Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!

Last Updated : 18 Jan, 2022
Like Article
Save Article
Previous
Next
Similar Reads
Complete Tutorials