如下图所示,有4个具有正整数半径r1 , r2 , r3和r4的圆。
任务是在给定半径r1 , r2 , r3的情况下,找到由三个圆组成的圆的半径r4 。
(请注意,上图中的圆圈彼此相切。)
例子:
Input: r1 = 1, r2 = 1, r3 = 1
Output: 0.154701
Input: r1 = 23, r2 = 46, r3 = 69
Output: 6.000000
方法1 :(使用二进制搜索):
- 政策是加入所有圆的中心并形成4个三角形
- 三角形形成后,使用二分查找法将三个较小三角形的面积之和与主三角形尽可能相等。
分析上述方法:
- 此方法之所以有效,是因为上面的图像中最初有4个三角形。
- 带边的主三角形和带有边的三个较小的三角形 。
- 主三角形由较小的三角形组成,因此主三角形的面积是较小三角形的面积之和。
形成搜索空间:
在这里二进制搜索。可以选择r的值,并且可以计算所有三个较小三角形的面积之和,并将其与主三角形的面积进行比较。
- 选择下限
- 选择上限
通过直觉,将r4的上限值作为内接圆的半径三角形小于:
r upper_bound
现在,可以在以下搜索空间中应用二进制搜索。
以下是使用上述方法实现的问题。
C++
// C++ implementation of the approach
#include
using namespace std;
// Radius of the 3 given circles
// declared as double.
double r1, r2, r3;
// Calculation of area of a triangle by Heron's formula
double area(double a, double b, double c)
{
double p = (a + b + c) / 2;
return sqrt(p) * sqrt(p - a) * sqrt(p - b) * sqrt(p - c);
}
// Applying binary search to find the
// radius r4 of the required circle
double binary_search()
{
// Area of main triangle
double s = area(r1 + r2, r2 + r3, r3 + r1);
double l = 0, h = s / (r1 + r2 + r3);
// Loop runs until l and h becomes approximately equal
while (h - l >= 1.e-7) {
double mid = (l + h) / 2;
// Area of smaller triangles
double s1 = area(mid + r1, mid + r2, r1 + r2);
double s2 = area(mid + r1, mid + r3, r1 + r3);
double s3 = area(mid + r2, mid + r3, r2 + r3);
// If sum of smaller triangles
// is less than main triangle
if (s1 + s2 + s3 < s) {
l = mid;
}
// If sum of smaller triangles is
// greater than or equal to main triangle
else {
h = mid;
}
}
return (l + h) / 2;
}
// Driver code
int main()
{
// Taking r1, r2, r3 as input
r1 = 1.0;
r2 = 2.0;
r3 = 3.0;
// Call to function binary search
cout << fixed << setprecision(6) << binary_search() << endl;
return 0;
}
Java
// Java implementation of the approach
import java.util.*;
class GFG
{
// Radius of the 3 given circles
// declared as double.
static double r1, r2, r3;
// Calculation of area of a triangle by Heron's formula
static double area(double a, double b, double c)
{
double p = (a + b + c) / 2;
return Math.sqrt(p) * Math.sqrt(p - a) *
Math.sqrt(p - b) * Math.sqrt(p - c);
}
// Applying binary search to find the
// radius r4 of the required circle
static double binary_search()
{
// Area of main triangle
double s = area(r1 + r2, r2 + r3, r3 + r1);
double l = 0, h = s / (r1 + r2 + r3);
// Loop runs until l and h becomes approximately equal
while (h - l >= 1.e-7)
{
double mid = (l + h) / 2;
// Area of smaller triangles
double s1 = area(mid + r1, mid + r2, r1 + r2);
double s2 = area(mid + r1, mid + r3, r1 + r3);
double s3 = area(mid + r2, mid + r3, r2 + r3);
// If sum of smaller triangles
// is less than main triangle
if (s1 + s2 + s3 < s)
{
l = mid;
}
// If sum of smaller triangles is
// greater than or equal to main triangle
else
{
h = mid;
}
}
return (l + h) / 2;
}
// Driver code
public static void main(String[] args)
{
// Taking r1, r2, r3 as input
r1 = 1.0;
r2 = 2.0;
r3 = 3.0;
// Call to function binary search
System.out.printf("%.6f", binary_search());
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 implementation of the approach
import math
# Radius of the 3 given circles
r1 = 0
r2 = 0
r3 = 0
# Calculation of area of a
# triangle by Heron's formula
def area(a, b, c):
p = (a + b + c) / 2
return ((math.sqrt(p)) *
(math.sqrt(p - a)) *
(math.sqrt(p - b)) *
(math.sqrt(p - c)))
# Applying binary search to find the
# radius r4 of the required circle
def binary_search():
global r1, r2, r3
# Area of main triangle
s = area(r1 + r2, r2 + r3, r3 + r1)
l = 0
h = s / (r1 + r2 + r3)
# Loop runs until l and h
# becomes approximately equal
while (h - l > 0.00000001):
mid = (l + h) / 2
# Area of smaller triangles
s1 = area(mid + r1, mid + r2, r1 + r2)
s2 = area(mid + r1, mid + r3, r1 + r3)
s3 = area(mid + r2, mid + r3, r2 + r3)
# If sum of smaller triangles
# is less than main triangle
if (s1 + s2 + s3 < s):
l = mid
# If sum of smaller triangles is
# greater than or equal to main triangle
else:
h = mid
return ((l + h) / 2)
# Driver code
# Taking r1, r2, r3 as input
r1 = 1
r2 = 2
r3 = 3
# Call to function binary search
print("{0:.6f}".format(binary_search()))
# This code is contributed by avanitrachhadiya2155
C#
// C# implementation of the approach
using System;
class GFG
{
// Radius of the 3 given circles
// declared as double.
static double r1, r2, r3;
// Calculation of area of a triangle by Heron's formula
static double area(double a, double b, double c)
{
double p = (a + b + c) / 2;
return Math.Sqrt(p) * Math.Sqrt(p - a) *
Math.Sqrt(p - b) * Math.Sqrt(p - c);
}
// Applying binary search to find the
// radius r4 of the required circle
static double binary_search()
{
// Area of main triangle
double s = area(r1 + r2, r2 + r3, r3 + r1);
double l = 0, h = s / (r1 + r2 + r3);
// Loop runs until l and h
// becomes approximately equal
while (h - l > 0.00000001)
{
double mid = (l + h) / 2;
// Area of smaller triangles
double s1 = area(mid + r1, mid + r2, r1 + r2);
double s2 = area(mid + r1, mid + r3, r1 + r3);
double s3 = area(mid + r2, mid + r3, r2 + r3);
// If sum of smaller triangles
// is less than main triangle
if (s1 + s2 + s3 < s)
{
l = mid;
}
// If sum of smaller triangles is
// greater than or equal to main triangle
else
{
h = mid;
}
}
return (l + h) / 2;
}
// Driver code
public static void Main(String[] args)
{
// Taking r1, r2, r3 as input
r1 = 1.0;
r2 = 2.0;
r3 = 3.0;
// Call to function binary search
Console.Write("{0:F6}", binary_search());
}
}
// This code is contributed by Rajput-Ji
C++
// C++ implementation of the approach
#include
using namespace std;
// Driver code
int main()
{
// Radius of the 3 given circles declared as double.
double r1, r2, r3;
// Taking r1, r2, r3 as input
r1 = 1;
r2 = 2;
r3 = 3;
// Calculation of r4 using formula given above
double r4 = (r1 * r2 * r3)
/ (r1 * r2 + r2 * r3 + r1 * r3
+ 2.0 * sqrt(r1 * r2 * r3 * (r1 + r2 + r3)));
cout << fixed << setprecision(6) << r4 << '\n';
return 0;
}
Java
// Java implementation of the approach
class GFG
{
// Driver code
public static void main(String[] args)
{
// Radius of the 3 given circles declared as double.
double r1, r2, r3;
// Taking r1, r2, r3 as input
r1 = 1;
r2 = 2;
r3 = 3;
// Calculation of r4 using formula given above
double r4 = (r1 * r2 * r3) /
(r1 * r2 + r2 * r3 + r1 * r3 + 2.0 *
Math.sqrt(r1 * r2 * r3 * (r1 + r2 + r3)));
System.out.printf("%.6f", r4);
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 implementation of the approach
from math import sqrt
# Driver code
# Radius of the 3 given circles declared as double.
# Taking r1, r2, r3 as input
r1 = 1
r2 = 2
r3 = 3
# Calculation of r4 using formula given above
r4 = (r1 * r2 * r3)/ (r1 * r2 + r2 * r3 + r1 * r3
+ 2.0 * sqrt(r1 * r2 * r3 * (r1 + r2 + r3)))
print(round(r4, 6))
# This code is contributed by mohit kumar 29
C#
// C# implementation of the approach
using System;
class GFG
{
// Driver code
public static void Main(String[] args)
{
// Radius of the 3 given circles declared as double.
double r1, r2, r3;
// Taking r1, r2, r3 as input
r1 = 1;
r2 = 2;
r3 = 3;
// Calculation of r4 using formula given above
double r4 = (r1 * r2 * r3) /
(r1 * r2 + r2 * r3 + r1 * r3 + 2.0 *
Math.Sqrt(r1 * r2 * r3 * (r1 + r2 + r3)));
Console.Write("{0:F6}", r4);
}
}
// This code contributed by PrinciRaj1992
输出:
0.260870
方法2 :(使用笛卡尔定理)
- 根据笛卡尔定理,这些圆的半径或“曲率”的倒数满足以下关系。
- 如果众所周知,一个人可以解决,
- 在求解上述方程式时;
以下是使用上述公式实现的问题。
C++
// C++ implementation of the approach
#include
using namespace std;
// Driver code
int main()
{
// Radius of the 3 given circles declared as double.
double r1, r2, r3;
// Taking r1, r2, r3 as input
r1 = 1;
r2 = 2;
r3 = 3;
// Calculation of r4 using formula given above
double r4 = (r1 * r2 * r3)
/ (r1 * r2 + r2 * r3 + r1 * r3
+ 2.0 * sqrt(r1 * r2 * r3 * (r1 + r2 + r3)));
cout << fixed << setprecision(6) << r4 << '\n';
return 0;
}
Java
// Java implementation of the approach
class GFG
{
// Driver code
public static void main(String[] args)
{
// Radius of the 3 given circles declared as double.
double r1, r2, r3;
// Taking r1, r2, r3 as input
r1 = 1;
r2 = 2;
r3 = 3;
// Calculation of r4 using formula given above
double r4 = (r1 * r2 * r3) /
(r1 * r2 + r2 * r3 + r1 * r3 + 2.0 *
Math.sqrt(r1 * r2 * r3 * (r1 + r2 + r3)));
System.out.printf("%.6f", r4);
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 implementation of the approach
from math import sqrt
# Driver code
# Radius of the 3 given circles declared as double.
# Taking r1, r2, r3 as input
r1 = 1
r2 = 2
r3 = 3
# Calculation of r4 using formula given above
r4 = (r1 * r2 * r3)/ (r1 * r2 + r2 * r3 + r1 * r3
+ 2.0 * sqrt(r1 * r2 * r3 * (r1 + r2 + r3)))
print(round(r4, 6))
# This code is contributed by mohit kumar 29
C#
// C# implementation of the approach
using System;
class GFG
{
// Driver code
public static void Main(String[] args)
{
// Radius of the 3 given circles declared as double.
double r1, r2, r3;
// Taking r1, r2, r3 as input
r1 = 1;
r2 = 2;
r3 = 3;
// Calculation of r4 using formula given above
double r4 = (r1 * r2 * r3) /
(r1 * r2 + r2 * r3 + r1 * r3 + 2.0 *
Math.Sqrt(r1 * r2 * r3 * (r1 + r2 + r3)));
Console.Write("{0:F6}", r4);
}
}
// This code contributed by PrinciRaj1992
输出:
0.260870
参考:
- https://brilliant.org/wiki/descartes-theorem/
- https://zh.wikipedia.org/wiki/Descartes%27_theorem/
- http://www.ambrsoft.com/TrigoCalc/Circles3/Tangency/Tangent.htm