📜  每秒扩展 1 个单位的 N 个圆中至少有 K 个重叠的最短时间

📅  最后修改于: 2022-05-13 01:56:06.289000             🧑  作者: Mango

每秒扩展 1 个单位的 N 个圆中至少有 K 个重叠的最短时间

给定2D无限平面上的N个点,其中每个点代表一个圆的中心,该圆的初始半径为0 ,以每秒1 个单位的恒定速率扩展,任务是找到至少K个圆的最短时间在一点重叠。

例子:

方法:给定的问题

C++
// C++ implementation of the above approach
#include 
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 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& 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 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


C++
// C++ implementation of the above approach
#include 
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 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& 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 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


可以通过使用以下观察的二进制搜索来解决:

  • 在任何给定时间t ,所有圆的半径必须为t 。因此,问题可以转化为找到最小半径,使得至少K个圆在给定点重叠。
  • 可以通过在[0, ∞]范围内对其执行二进制搜索来计算所需的最小半径。

现在,所需的任务是检查给定的半径r ,如果任意点的半径为r的重叠圆的计数大于或等于K 。可以使用以下技术来完成:

  • 遍历给定圆的所有可能的无序对并检查它们是否相互交叉。假设它们彼此相交。那么这种情况可以用下图来解释:

  • 任务是计算P1P2的值,可以通过以下过程完成:

因此,对于所有可能的相交圆对,计算P1P2的值并计算圆的计数,使得P1位于变量cnt1中的那个圆中,并类似地计算圆的计数,使得P2位于变量 cnt1 中的那个圆中变量cnt2 。如果cnt1cnt2的任何值大于K ,这意味着对于给定的r = mid ,平面中存在一个点,使得至少K个圆在其上重叠。

下面是上述方法的实现:

C++

// C++ implementation of the above approach
#include 
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 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& 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 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


输出
5

时间复杂度: O(N 3 * log N)
辅助空间: O(1)