给定一个大小为N的数组arr[][] ,由坐标对组成,使得arr[i][0]和arr[i][1]表示二维平面中的X和Y坐标。给定另一个数组V[] ,它表示任何方向上每个点的最大速度,任务是找到最短时间,使所有给定点在 2D 平面中的任意点相遇。
例子:
Input: N = 4, arr[][] = {{1, 2}, {-3, 34}, {-1, -2}, {2, -2}}, V[] = {3, 2, 4, 5}
Output: 1.1157499537009508
Input: N = 2, arr[][] = {{1. 2}, {-1, -2}}, V[] = {2, 3}
Output: 0.8944271909999159
方法:根据以下观察可以解决给定的问题:
- 在坐标轴给定的N个点可以在任何方向移动,并且,如果这些点被允许移动对于T的时间,然后它们可以到达圆内的任何点(通过降低V [I]相应地)具有半径等于V [I ] * T和中心等于该点的初始位置,其中V[i]代表第i个点的速度。
- 因此,为了最小化的这N个圆半径需要的公共区域被最小化,并且,如果存在在时间T的共同的交汇点然后必须存在一个交汇点T“> T作为会有对于T更常见区域” .
- 因此,该想法是检查公共交汇点的存在,即检查是否存在N 个圆的公共区域。
- 下面是3 个圆的所有可能组合的说明,每个圆都有一个非零的交点面积,那么所有 3 个圆都有一个公共的交点面积:
- 在图1、2、3、4、5中,三个圆中两个圆的半径之和小于它们之间的距离,这意味着三个圆之间没有公共区域。
- 在图 6、7、8、9 中,一个或两个圆位于另一个圆内。
- 在图 10、11、12、13 中找到两个圆之间的交点,并检查这些交点是否在另一个圆内。
从上述观察中,我们的想法是使用二分搜索为所有给定的N 个点找到具有唯一交点的最短时间。请按照以下步骤解决给定的问题:
- 声明一个函数,比如intersection(X1, Y1, R1, X2, Y2, R2, X3, Y3, R3) ,它以圆的坐标和半径为参数,并执行以下步骤:
- 如果任何两个圆的半径之和小于它们中心之间的距离之和,则返回false,因为它们之间不存在任何这样的公共区域。
- 现在,检查任意两个圆是否有公共区域。如果发现为true ,则返回true 。否则,返回false 。
- 声明一个函数,比如isGood(mid, N, X, Y, V) ,它将当前可能的时间、 N 个点的坐标和每个点的速度作为参数,并执行以下步骤:
- 如果N的值至少为 3 ,则通过调用函数intersection(X1, Y1, R1, X2, Y2, R2, X3, Y3, R3)检查三个圆的所有可能组合以获得公共区域。如果存在没有任何公共区域的任何此类组合,则返回false 。否则,返回true 。
- 如果N 的值为2 ,则检查两个圆是否有公共区域。如果发现为true ,则返回true 。否则,返回false 。
- 初始化两个变量,比如tl为0.0和tu为100000.0,分别作为获得唯一交点所需的最小和最大时间。
- 现在,迭代范围[0, 1000]以获得更好的结果时间精度,并按照以下步骤执行二分搜索:
- 找到中间值,比如mid为(tl + tu)/2.0 。
- 现在通过调用函数isGood(mid, N, X, Y, V)检查上面的时间mid是否至少有一个公共的交叉区域。如果发现为true ,则将tu更新为mid 。否则,将tl更新为t 。
- 完成上述步骤后,打印tu的值作为所有给定的N 个点相交的最小时间。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to check for common area
// between three circles
bool intersection(int X1, int Y1, double R1,
int X2, int Y2, double R2,
int X3, int Y3, double R3)
{
// Find the distance between the
// centers of circle 1 & circle 2
double d12 = sqrt((X1 - X2) * (X1 - X2)
+ (Y1 - Y2) * (Y1 - Y2));
// Find the distance between the
// centers of circle 1 & circle 3
double d13 = sqrt((X1 - X3) * (X1 - X3)
+ (Y1 - Y3) * (Y1 - Y3));
// Find the distance between the
// centers of circle 2 & circle 3
double d23 = sqrt((X2 - X3) * (X2 - X3)
+ (Y2 - Y3) * (Y2 - Y3));
// If sum of radius is less than
// the distance between their
// centers then false
if ((R1 + R2 < d12) || (R1 + R3 < d13)
|| (R2 + R3 < d23)) {
return false;
}
else {
// If circle 1 lies within
// circle 2 or if circle
// 2 lies within circle 1
if (abs(R1 - R2) >= d12) {
// If circle 1 lies
// within circle 2
if (R1 < R2) {
// Check whether R1
// (common area between
// R1 and R2) and
// R3 intersect
return R1 + R3 >= d13;
}
else {
// Check whether R2
//(common area between
// R1 and R2) and
// R3 intersect
return R2 + R3 >= d23;
}
}
// If circle 1 lies within
// circle 3 or if circle
// 3 lies within circle 1
else if (abs(R1 - R3) >= d13) {
// If circle 1 lies
// within circle 3
if (R1 < R3) {
// Check whether R1
// (common area between
// R1 and R3) and
// R2 intersect
return R1 + R2 >= d12;
}
else {
// Check whether R3
//(common area between
// R1 and R3) and
// R2 intersect
return R2 + R3 >= d23;
}
}
// If circle 2 lies within
// circle 3 or if circle
// 3 lies within circle 2
else if (abs(R2 - R3) >= d23) {
// If circle 2
// lies within circle 3
if (R2 < R3) {
// Check whether R2
// (common area between
// R2 and R3) and
// R1 intersect
return R1 + R2 >= d12;
}
else {
// Check whether R3
// (common area between
// R2 and R3) and
// R1 intersect
return R1 + R3 >= d13;
}
}
else
{
double x121, y121, x122,
y122, x131, y131,
x132, y132, x231,
y231, x232, y232,
a, b;
// Find the point of
// intersection for
// circle 1 & circle 2
a = (R1 * R1 - R2 * R2)
/ (2 * d12 * d12);
b = sqrt(2 * (R1 * R1 + R2 * R2)
/ (d12 * d12)
- (R1 * R1 - R2 * R2)
* (R1 * R1 - R2 * R2)
/ (pow(d12, 4))
- 1)
/ 2;
// First point of
// intersection (x121, y121)
x121 = (X1 + X2) / 2.0 + a * (X2 - X1)
+ b * (Y2 - Y1);
y121 = (Y1 + Y2) / 2.0 + a * (Y2 - Y1)
+ b * (X1 - X2);
// Check whether the point
// of intersection lies
// within circle 3 or not
if (R3 >= sqrt(
(x121 - X3) * (x121 - X3)
+ (y121 - Y3) * (y121 - Y3))) {
return true;
}
// Second point of
// intersection(x122, y122)
x122 = (X1 + X2) / 2.0 + a * (X2 - X1)
- b * (Y2 - Y1);
y122 = (Y1 + Y2) / 2.0 + a * (Y2 - Y1)
- b * (X1 - X2);
// Check whether the point
// of intersection lies
// within circle 3 or not
if (R3 >= sqrt(
(x122 - X3) * (x122 - X3)
+ (y122 - Y3) * (y122 - Y3))) {
return true;
}
// Find the point of
// intersection for
// circle 1 & circle 3
a = (R1 * R1 - R3 * R3) / (2 * d13 * d13);
b = sqrt(2 * (R1 * R1 + R3 * R3)
/ (d13 * d13)
- (R1 * R1 - R3 * R3)
* (R1 * R1 - R3 * R3)
/ (pow(d13, 4))
- 1)
/ 2;
// First point of
// intersection(x131, y131)
x131 = (X1 + X3) / 2.0 + a * (X3 - X1)
+ b * (Y3 - Y1);
y131 = (Y1 + Y3) / 2.0 + a * (Y3 - Y1)
+ b * (X1 - X3);
// Check whether the point
// of intersection lies
// within circle 2 or not
if (R2 >= sqrt(
(x131 - X2) * (x131 - X2)
+ (y131 - Y2) * (y131 - Y2))) {
return true;
}
// Second point of
// intersection(x132, y132)
x132 = (X1 + X3) / 2.0 + a * (X3 - X1)
- b * (Y3 - Y1);
y132 = (Y1 + Y3) / 2.0 + a * (Y3 - Y1)
- b * (X1 - X3);
// Check whether the point
// of intersection lies
// within circle 2 or not
if (R2 >= sqrt(
(x132 - X2) * (x132 - X2)
+ (y132 - Y2) * (y132 - Y2))) {
return true;
}
// Find the point of
// intersection for
// circle 2 & circle 3
a = (R2 * R2 - R3 * R3) / (2 * d23 * d23);
b = sqrt(2 * (R2 * R2 + R3 * R3)
/ (d23 * d23)
- (R2 * R2 - R3 * R3)
* (R2 * R2 - R3 * R3)
/ (pow(d23, 4))
- 1)
/ 2;
// First point of
// intersection(x231, y231)
x231 = (X2 + X3) / 2.0 + a * (X3 - X2)
+ b * (Y3 - Y2);
y231 = (Y2 + Y3) / 2.0 + a * (Y3 - Y2)
+ b * (X2 - X3);
// Check whether the point
// of intersection lies
// within circle 1 or not
if (R1 >= sqrt(
(x231 - X1) * (x231 - X1)
+ (y231 - Y1) * (y231 - Y1))) {
return true;
}
// Second point of
// intersection(x232, y232)
x232 = (X2 + X3) / 2.0 + a * (X3 - X2)
- b * (Y3 - Y2);
y232 = (Y2 + Y3) / 2.0 + a * (Y3 - Y2)
- b * (X2 - X3);
// Check whether the point
// of intersection lies
// within circle 1 or not
return R1 >= sqrt(
(x232 - X1) * (x232 - X1)
+ (y232 - Y1) * (y232 - Y1));
}
}
}
// Function to check if there is
// a common area between N
// circles
bool isGood(double t, int N, int X[],
int Y[], int V[])
{
if (N >= 3) {
// Check for a common area
// for all combination
// of 3 circles
for (int i = 0; i < N; i++) {
for (int j = i + 1; j < N; j++) {
for (int k = j + 1; k < N; k++) {
// t * V give the
// radius of the circle
if (intersection(
X[i], Y[i], t * V[i], X[j],
Y[j], t * V[j], X[k], Y[k],
t * V[k]) == false)
return false;
}
}
}
return true;
}
// For N = 2
else {
//(x2 - x1) ^ 2 + (y2 - y1) ^ 2 <=
//(r1 + r2) ^ 2 for 2 circles
// to intersect
return sqrt((X[0] - X[1])
* (X[0] - X[1])
+ (Y[0] - Y[1])
* (Y[0] - Y[1]))
<= t * (V[0] + V[1]);
}
}
// Function to find minimum time
void binarySearch(int N, int X[], int Y[], int V[])
{
// Time depends on the area
// of the 2D plane
// Area =(Max(X) - Min(X))*
// (Max(Y) - Min(Y))
double tl = 0.0, tu = 100000.0, t;
// Number of iteration
// depends on the precision
for (int i = 0; i < 1000; i++) {
t = (tl + tu) / 2.0;
// If there is a common area
// between N circles
// for time t
if (isGood(t, N, X, Y, V)) {
tu = t;
}
// If there is no common area
// between N circles
// for time t
else {
tl = t;
}
}
// Print the minimum time
cout << fixed << setprecision(16) << tu << endl;
}
// Driver Code
int main()
{
int N = 4;
int X[] = { 1, -3, -1, 2 };
int Y[] = { 2, 4, -2, -2 };
int V[] = { 3, 2, 4, 5 };
// Function Call
binarySearch(N, X, Y, V);
}
// This code is contributed by ipg2016107.
Java
// Java program for the above approach
class GFG {
// Function to check for common area
// between three circles
public static boolean
intersection(int X1, int Y1, double R1,
int X2, int Y2, double R2,
int X3, int Y3, double R3)
{
// Find the distance between the
// centers of circle 1 & circle 2
double d12 = Math.sqrt((X1 - X2) * (X1 - X2)
+ (Y1 - Y2) * (Y1 - Y2));
// Find the distance between the
// centers of circle 1 & circle 3
double d13 = Math.sqrt((X1 - X3) * (X1 - X3)
+ (Y1 - Y3) * (Y1 - Y3));
// Find the distance between the
// centers of circle 2 & circle 3
double d23 = Math.sqrt((X2 - X3) * (X2 - X3)
+ (Y2 - Y3) * (Y2 - Y3));
// If sum of radius is less than
// the distance between their
// centers then false
if ((R1 + R2 < d12) || (R1 + R3 < d13)
|| (R2 + R3 < d23)) {
return false;
}
else {
// If circle 1 lies within
// circle 2 or if circle
// 2 lies within circle 1
if (Math.abs(R1 - R2) >= d12) {
// If circle 1 lies
// within circle 2
if (R1 < R2) {
// Check whether R1
// (common area between
// R1 and R2) and
// R3 intersect
return R1 + R3 >= d13;
}
else {
// Check whether R2
//(common area between
// R1 and R2) and
// R3 intersect
return R2 + R3 >= d23;
}
}
// If circle 1 lies within
// circle 3 or if circle
// 3 lies within circle 1
else if (Math.abs(R1 - R3) >= d13) {
// If circle 1 lies
// within circle 3
if (R1 < R3) {
// Check whether R1
// (common area between
// R1 and R3) and
// R2 intersect
return R1 + R2 >= d12;
}
else {
// Check whether R3
//(common area between
// R1 and R3) and
// R2 intersect
return R2 + R3 >= d23;
}
}
// If circle 2 lies within
// circle 3 or if circle
// 3 lies within circle 2
else if (Math.abs(R2 - R3) >= d23) {
// If circle 2
// lies within circle 3
if (R2 < R3) {
// Check whether R2
// (common area between
// R2 and R3) and
// R1 intersect
return R1 + R2 >= d12;
}
else {
// Check whether R3
// (common area between
// R2 and R3) and
// R1 intersect
return R1 + R3 >= d13;
}
}
else {
double x121, y121, x122,
y122, x131, y131,
x132, y132, x231,
y231, x232, y232,
a, b;
// Find the point of
// intersection for
// circle 1 & circle 2
a = (R1 * R1 - R2 * R2)
/ (2 * d12 * d12);
b = Math.sqrt(2 * (R1 * R1 + R2 * R2)
/ (d12 * d12)
- (R1 * R1 - R2 * R2)
* (R1 * R1 - R2 * R2)
/ (Math.pow(d12, 4))
- 1)
/ 2;
// First point of
// intersection (x121, y121)
x121 = (X1 + X2) / 2.0 + a * (X2 - X1)
+ b * (Y2 - Y1);
y121 = (Y1 + Y2) / 2.0 + a * (Y2 - Y1)
+ b * (X1 - X2);
// Check whether the point
// of intersection lies
// within circle 3 or not
if (R3 >= Math.sqrt(
(x121 - X3) * (x121 - X3)
+ (y121 - Y3) * (y121 - Y3))) {
return true;
}
// Second point of
// intersection(x122, y122)
x122 = (X1 + X2) / 2.0 + a * (X2 - X1)
- b * (Y2 - Y1);
y122 = (Y1 + Y2) / 2.0 + a * (Y2 - Y1)
- b * (X1 - X2);
// Check whether the point
// of intersection lies
// within circle 3 or not
if (R3 >= Math.sqrt(
(x122 - X3) * (x122 - X3)
+ (y122 - Y3) * (y122 - Y3))) {
return true;
}
// Find the point of
// intersection for
// circle 1 & circle 3
a = (R1 * R1 - R3 * R3) / (2 * d13 * d13);
b = Math.sqrt(2 * (R1 * R1 + R3 * R3)
/ (d13 * d13)
- (R1 * R1 - R3 * R3)
* (R1 * R1 - R3 * R3)
/ (Math.pow(d13, 4))
- 1)
/ 2;
// First point of
// intersection(x131, y131)
x131 = (X1 + X3) / 2.0 + a * (X3 - X1)
+ b * (Y3 - Y1);
y131 = (Y1 + Y3) / 2.0 + a * (Y3 - Y1)
+ b * (X1 - X3);
// Check whether the point
// of intersection lies
// within circle 2 or not
if (R2 >= Math.sqrt(
(x131 - X2) * (x131 - X2)
+ (y131 - Y2) * (y131 - Y2))) {
return true;
}
// Second point of
// intersection(x132, y132)
x132 = (X1 + X3) / 2.0 + a * (X3 - X1)
- b * (Y3 - Y1);
y132 = (Y1 + Y3) / 2.0 + a * (Y3 - Y1)
- b * (X1 - X3);
// Check whether the point
// of intersection lies
// within circle 2 or not
if (R2 >= Math.sqrt(
(x132 - X2) * (x132 - X2)
+ (y132 - Y2) * (y132 - Y2))) {
return true;
}
// Find the point of
// intersection for
// circle 2 & circle 3
a = (R2 * R2 - R3 * R3) / (2 * d23 * d23);
b = Math.sqrt(2 * (R2 * R2 + R3 * R3)
/ (d23 * d23)
- (R2 * R2 - R3 * R3)
* (R2 * R2 - R3 * R3)
/ (Math.pow(d23, 4))
- 1)
/ 2;
// First point of
// intersection(x231, y231)
x231 = (X2 + X3) / 2.0 + a * (X3 - X2)
+ b * (Y3 - Y2);
y231 = (Y2 + Y3) / 2.0 + a * (Y3 - Y2)
+ b * (X2 - X3);
// Check whether the point
// of intersection lies
// within circle 1 or not
if (R1 >= Math.sqrt(
(x231 - X1) * (x231 - X1)
+ (y231 - Y1) * (y231 - Y1))) {
return true;
}
// Second point of
// intersection(x232, y232)
x232 = (X2 + X3) / 2.0 + a * (X3 - X2)
- b * (Y3 - Y2);
y232 = (Y2 + Y3) / 2.0 + a * (Y3 - Y2)
- b * (X2 - X3);
// Check whether the point
// of intersection lies
// within circle 1 or not
return R1 >= Math.sqrt(
(x232 - X1) * (x232 - X1)
+ (y232 - Y1) * (y232 - Y1));
}
}
}
// Function to check if there is
// a common area between N
// circles
public static boolean isGood(double t, int N, int[] X,
int[] Y, int[] V)
{
if (N >= 3) {
// Check for a common area
// for all combination
// of 3 circles
for (int i = 0; i < N; i++) {
for (int j = i + 1; j < N; j++) {
for (int k = j + 1; k < N; k++) {
// t * V give the
// radius of the circle
if (!intersection(
X[i], Y[i], t * V[i], X[j],
Y[j], t * V[j], X[k], Y[k],
t * V[k]))
return false;
}
}
}
return true;
}
// For N = 2
else {
//(x2 - x1) ^ 2 + (y2 - y1) ^ 2 <=
//(r1 + r2) ^ 2 for 2 circles
// to intersect
return Math.sqrt((X[0] - X[1])
* (X[0] - X[1])
+ (Y[0] - Y[1])
* (Y[0] - Y[1]))
<= t * (V[0] + V[1]);
}
}
// Function to find minimum time
public static void binarySearch(int N, int[] X,
int[] Y, int[] V)
{
// Time depends on the area
// of the 2D plane
// Area =(Max(X) - Min(X))*
// (Max(Y) - Min(Y))
double tl = 0.0, tu = 100000.0, t;
// Number of iteration
// depends on the precision
for (int i = 0; i < 1000; i++) {
t = (tl + tu) / 2.0;
// If there is a common area
// between N circles
// for time t
if (isGood(t, N, X, Y, V)) {
tu = t;
}
// If there is no common area
// between N circles
// for time t
else {
tl = t;
}
}
// Print the minimum time
System.out.println(tu);
}
// Driver Code
public static void main(String[] args)
{
int N = 4;
int[] X = { 1, -3, -1, 2 };
int[] Y = { 2, 4, -2, -2 };
int[] V = { 3, 2, 4, 5 };
// Function Call
binarySearch(N, X, Y, V);
}
}
C#
// C# program for the above approach
using System;
class GFG{
// Function to check for common area
// between three circles
public static bool intersection(int X1, int Y1, double R1,
int X2, int Y2, double R2,
int X3, int Y3, double R3)
{
// Find the distance between the
// centers of circle 1 & circle 2
double d12 = Math.Sqrt((X1 - X2) * (X1 - X2) +
(Y1 - Y2) * (Y1 - Y2));
// Find the distance between the
// centers of circle 1 & circle 3
double d13 = Math.Sqrt((X1 - X3) * (X1 - X3) +
(Y1 - Y3) * (Y1 - Y3));
// Find the distance between the
// centers of circle 2 & circle 3
double d23 = Math.Sqrt((X2 - X3) * (X2 - X3) +
(Y2 - Y3) * (Y2 - Y3));
// If sum of radius is less than
// the distance between their
// centers then false
if ((R1 + R2 < d12) || (R1 + R3 < d13) ||
(R2 + R3 < d23))
{
return false;
}
else
{
// If circle 1 lies within
// circle 2 or if circle
// 2 lies within circle 1
if (Math.Abs(R1 - R2) >= d12)
{
// If circle 1 lies
// within circle 2
if (R1 < R2)
{
// Check whether R1
// (common area between
// R1 and R2) and
// R3 intersect
return R1 + R3 >= d13;
}
else
{
// Check whether R2
//(common area between
// R1 and R2) and
// R3 intersect
return R2 + R3 >= d23;
}
}
// If circle 1 lies within
// circle 3 or if circle
// 3 lies within circle 1
else if (Math.Abs(R1 - R3) >= d13)
{
// If circle 1 lies
// within circle 3
if (R1 < R3)
{
// Check whether R1
// (common area between
// R1 and R3) and
// R2 intersect
return R1 + R2 >= d12;
}
else
{
// Check whether R3
//(common area between
// R1 and R3) and
// R2 intersect
return R2 + R3 >= d23;
}
}
// If circle 2 lies within
// circle 3 or if circle
// 3 lies within circle 2
else if (Math.Abs(R2 - R3) >= d23)
{
// If circle 2
// lies within circle 3
if (R2 < R3)
{
// Check whether R2
// (common area between
// R2 and R3) and
// R1 intersect
return R1 + R2 >= d12;
}
else
{
// Check whether R3
// (common area between
// R2 and R3) and
// R1 intersect
return R1 + R3 >= d13;
}
}
else
{
double x121, y121, x122,
y122, x131, y131,
x132, y132, x231,
y231, x232, y232,
a, b;
// Find the point of
// intersection for
// circle 1 & circle 2
a = (R1 * R1 - R2 * R2) /
(2 * d12 * d12);
b = Math.Sqrt(2 * (R1 * R1 + R2 * R2) /
(d12 * d12) - (R1 * R1 - R2 * R2) *
(R1 * R1 - R2 * R2) /
(Math.Pow(d12, 4)) - 1) / 2;
// First point of
// intersection (x121, y121)
x121 = (X1 + X2) / 2.0 + a * (X2 - X1) +
b * (Y2 - Y1);
y121 = (Y1 + Y2) / 2.0 + a * (Y2 - Y1) +
b * (X1 - X2);
// Check whether the point
// of intersection lies
// within circle 3 or not
if (R3 >= Math.Sqrt((x121 - X3) * (x121 - X3) +
(y121 - Y3) * (y121 - Y3)))
{
return true;
}
// Second point of
// intersection(x122, y122)
x122 = (X1 + X2) / 2.0 + a * (X2 - X1) -
b * (Y2 - Y1);
y122 = (Y1 + Y2) / 2.0 + a * (Y2 - Y1) -
b * (X1 - X2);
// Check whether the point
// of intersection lies
// within circle 3 or not
if (R3 >= Math.Sqrt((x122 - X3) * (x122 - X3) +
(y122 - Y3) * (y122 - Y3)))
{
return true;
}
// Find the point of
// intersection for
// circle 1 & circle 3
a = (R1 * R1 - R3 * R3) / (2 * d13 * d13);
b = Math.Sqrt(2 * (R1 * R1 + R3 * R3) /
(d13 * d13) - (R1 * R1 - R3 * R3) *
(R1 * R1 - R3 * R3) /
(Math.Pow(d13, 4)) - 1) / 2;
// First point of
// intersection(x131, y131)
x131 = (X1 + X3) / 2.0 + a * (X3 - X1) +
b * (Y3 - Y1);
y131 = (Y1 + Y3) / 2.0 + a * (Y3 - Y1) +
b * (X1 - X3);
// Check whether the point
// of intersection lies
// within circle 2 or not
if (R2 >= Math.Sqrt((x131 - X2) * (x131 - X2) +
(y131 - Y2) * (y131 - Y2)))
{
return true;
}
// Second point of
// intersection(x132, y132)
x132 = (X1 + X3) / 2.0 + a * (X3 - X1) -
b * (Y3 - Y1);
y132 = (Y1 + Y3) / 2.0 + a * (Y3 - Y1) -
b * (X1 - X3);
// Check whether the point
// of intersection lies
// within circle 2 or not
if (R2 >= Math.Sqrt((x132 - X2) * (x132 - X2) +
(y132 - Y2) * (y132 - Y2)))
{
return true;
}
// Find the point of
// intersection for
// circle 2 & circle 3
a = (R2 * R2 - R3 * R3) / (2 * d23 * d23);
b = Math.Sqrt(2 * (R2 * R2 + R3 * R3) /
(d23 * d23) - (R2 * R2 - R3 * R3) *
(R2 * R2 - R3 * R3) /
(Math.Pow(d23, 4)) - 1) / 2;
// First point of
// intersection(x231, y231)
x231 = (X2 + X3) / 2.0 + a * (X3 - X2) +
b * (Y3 - Y2);
y231 = (Y2 + Y3) / 2.0 + a * (Y3 - Y2) +
b * (X2 - X3);
// Check whether the point
// of intersection lies
// within circle 1 or not
if (R1 >= Math.Sqrt((x231 - X1) * (x231 - X1) +
(y231 - Y1) * (y231 - Y1)))
{
return true;
}
// Second point of
// intersection(x232, y232)
x232 = (X2 + X3) / 2.0 + a * (X3 - X2) -
b * (Y3 - Y2);
y232 = (Y2 + Y3) / 2.0 + a * (Y3 - Y2) -
b * (X2 - X3);
// Check whether the point
// of intersection lies
// within circle 1 or not
return R1 >= Math.Sqrt((x232 - X1) * (x232 - X1) +
(y232 - Y1) * (y232 - Y1));
}
}
}
// Function to check if there is
// a common area between N
// circles
public static bool isGood(double t, int N, int[] X,
int[] Y, int[] V)
{
if (N >= 3)
{
// Check for a common area
// for all combination
// of 3 circles
for(int i = 0; i < N; i++)
{
for(int j = i + 1; j < N; j++)
{
for(int k = j + 1; k < N; k++)
{
// t * V give the
// radius of the circle
if (!intersection(X[i], Y[i], t * V[i],
X[j], Y[j], t * V[j],
X[k], Y[k], t * V[k]))
return false;
}
}
}
return true;
}
// For N = 2
else
{
//(x2 - x1) ^ 2 + (y2 - y1) ^ 2 <=
//(r1 + r2) ^ 2 for 2 circles
// to intersect
return Math.Sqrt((X[0] - X[1]) * (X[0] - X[1]) +
(Y[0] - Y[1]) * (Y[0] - Y[1])) <=
t * (V[0] + V[1]);
}
}
// Function to find minimum time
public static void binarySearch(int N, int[] X,
int[] Y, int[] V)
{
// Time depends on the area
// of the 2D plane
// Area =(Max(X) - Min(X))*
// (Max(Y) - Min(Y))
double tl = 0.0, tu = 100000.0, t;
// Number of iteration
// depends on the precision
for(int i = 0; i < 1000; i++)
{
t = (tl + tu) / 2.0;
// If there is a common area
// between N circles
// for time t
if (isGood(t, N, X, Y, V))
{
tu = t;
}
// If there is no common area
// between N circles
// for time t
else
{
tl = t;
}
}
// Print the minimum time
Console.WriteLine(tu);
}
// Driver Code
public static void Main(string[] args)
{
int N = 4;
int[] X = { 1, -3, -1, 2 };
int[] Y = { 2, 4, -2, -2 };
int[] V = { 3, 2, 4, 5 };
// Function Call
binarySearch(N, X, Y, V);
}
}
// This code is contributed by AnkThon
输出:
1.1157499537009508
时间复杂度: O(N 3 )
辅助空间: O(1)