📜  N点重合所需的最短时间

📅  最后修改于: 2021-04-17 18:36:15             🧑  作者: Mango

给定大小为N的数组arr [] [] ,该数组由成对的坐标组成,使得arr [i] [0]arr [i] [1]表示2D平面中的XY坐标。给定另一个数组V [] ,它表示每个方向上每个点的最大速度,任务是找到最小时间,以使所有给定点在2D平面中的任意点处相遇。

例子:

方法:可以根据以下观察结果解决给定问题:

  • 在坐标轴给定的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个点具有唯一交点的最短时间。请按照以下步骤解决给定的问题:

  • 声明一个函数,例如以圆的坐标和半径为参数的交集(X1,Y1,R1,X2,Y2,R2,X3,Y3,R3) ,并执行以下步骤:
    • 如果两个圆的半径之和小于两个圆心的距离之和,则返回false,因为它们之间不存在任何此类公共区域。
    • 现在,检查是否有两个圆圈具有公共区域。如果发现为true ,则返回true 。否则,返回false
  • 声明一个函数,例如isGood(mid,N,X,Y,V) ,该函数将当前可能的时间, N个点的坐标以及每个点的速度作为参数,并执行以下步骤:
    • 如果N的值至少为3 ,则通过调用函数cross(X1,Y1,R1,X2,Y2,R2,X3,Y3,R3)检查三个圆的所有可能组合以获得公共区域。如果存在没有任何公共区域的任何此类组合,则返回false 。否则,返回true
    • 如果N的值为2 ,则检查两个圆是否具有公共区域。如果发现为true ,则返回true 。否则,返回false
  • 初始化两个变量,例如,将tl设置0.0 ,将tu设置100000.0,分别作为获取唯一交点所需的最短时间和最大时间。
  • 现在,在[0,1000]范围内进行迭代以获得更好的结果时间精度,并按照以下步骤执行二进制搜索:
    • 找到中间值,即作为中期(TL + TU)/2.0。
    • 现在检查如果上述时间中间具有交点的至少一个共同的区域或不通过调用函数isGood(中旬,N,X,Y,V)。如果发现是正确的,则将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)