每秒扩展 1 个单位的 N 个圆中至少有 K 个重叠的最短时间
给定2D无限平面上的N个点,其中每个点代表一个圆的中心,该圆的初始半径为0 ,以每秒1 个单位的恒定速率扩展,任务是找到至少K个圆的最短时间在一点重叠。
例子:
Input: points[] = {{8, 5}, {0, 4}, {3, 6}}, K = 3
Output: 5
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: 1
方法:给定的问题
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 。可以使用以下技术来完成:
- 遍历给定圆的所有可能的无序对并检查它们是否相互交叉。假设它们彼此相交。那么这种情况可以用下图来解释:
- 任务是计算P1和P2的值,可以通过以下过程完成:
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)
因此,对于所有可能的相交圆对,计算P1和P2的值并计算圆的计数,使得P1位于变量cnt1中的那个圆中,并类似地计算圆的计数,使得P2位于变量 cnt1 中的那个圆中变量cnt2 。如果cnt1和cnt2的任何值大于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)