给定两个圆和一个长度 K。找出我们是否可以连接两个点(每个圆的周长上有一个),使点之间的距离为 K。(两个点的坐标不必是整数值)。
例子:
Input: Circle-1 Center (0, 0) Radius = 5
Circle-2 Center (8, 3) Radius = 2
K = 3
Output: Yes
Maximum Distance: 15
Minimum Distance: 2
方法:
- 我们必须找到这些圆上任意两点之间可能的最大和最小距离,如果 K 在这个范围内,那么答案是肯定的,否则我们找不到这样的线段。
- 要查找最小和最大距离:
- 情况 1:当两个圆不相交或仅接触一点时。
在这种情况下,最大距离将是中心之间的距离 + 半径(圆 1)+ 半径(圆 2)。最小距离将是中心之间的距离 – 半径(圆 1) – 半径(圆 2)。
- 情况 2:当两个圆恰好在两点相交时。
在这种情况下,最大距离将是中心之间的距离 + 半径(圆 1)+ 半径(圆 2)。最小距离为 0。(我们在两个圆中有两个共同点)。
- 情况 3:当圆 1 完全在圆 2 内时。
在这种情况下,最大距离将是中心之间的距离 + 半径(圆 1)+ 半径(圆 2)。最小距离为半径(圆 2) – 中心之间的距离 – 半径(圆 1)
- 情况 4:当圆 2 完全在圆 1 内时。
在这种情况下,最大距离将是中心之间的距离 + 半径(圆 1)+ 半径(圆 2)。最小距离为半径(圆 1) – 中心之间的距离 – 半径(圆 2)
- 情况 5:当两个圆的中心相同时
- 子案例1:半径也相同。最小距离和最大距离均为 0。
- 子案例2:半径不同(R1
最大距离为 R1+R2
最小距离为 R2-R1
下面是上述方法的实现:
C++
// C++ program to implement above approach
#include
#define ll long long int
using namespace std;
struct t {
ll x, y, r;
};
typedef struct t node;
// Return distance between the centers
long double dis(ll x1, ll y1, ll x2, ll y2)
{
return sqrt((x1 - x2) * (x1 - x2)
+ (y1 - y2) * (y1 - y2));
}
bool check(node c1, node c2, int k)
{
long double min = 0;
long double max = 0;
// Distance between centers
long double de = dis(c1.x, c1.y, c2.x, c2.y);
// Case 5
if (de == 0) {
// SubCase 1
if (c1.r == c2.r) {
min = 0;
max = 0;
}
// Subcase 2
else {
if (c1.r - c2.r > 0) {
min = c1.r - c2.r;
max = min + 2 * c2.r;
}
else {
min = c2.r - c1.r;
max = min + 2 * c1.r;
}
}
}
// Case 1
else if (de >= c1.r + c2.r) {
min = de - c1.r - c2.r;
max = de + c1.r + c2.r;
}
// Case 3
else if (de + c2.r < c1.r) {
max = c2.r + c1.r + de;
min = c1.r - de - c2.r;
}
// Case 4
else if (de + c1.r < c2.r) {
max = c2.r + c1.r + de;
min = c2.r - de - c1.r;
}
// Case 2
else if ((de + c2.r >= c1.r) || (de + c1.r >= c2.r)) {
max = c2.r + c1.r + de;
min = 0;
}
// Since value of k will always be an integer
ll temin = (ll)(ceil(min));
ll re = (ll)max;
if (k >= temin && k <= re)
return true;
return false;
}
// Driver Code
int main()
{
node circle1, circle2;
int k = 3;
circle1.x = 0;
circle1.y = 0;
circle1.r = 5;
circle2.x = 8;
circle2.y = 3;
circle2.r = 2;
if (check(circle1, circle2, k))
cout << "YES" << endl;
else
cout << "NO" << endl;
}
Java
// Java program to implement above approach
class GFG
{
static class node
{
long x, y, r;
};
// Return distance between the centers
static long dis(long x1, long y1, long x2, long y2)
{
return (long) Math.sqrt((x1 - x2) * (x1 - x2)
+ (y1 - y2) * (y1 - y2));
}
static boolean check(node c1, node c2, int k)
{
long min = 0;
long max = 0;
// Distance between centers
long de = dis(c1.x, c1.y, c2.x, c2.y);
// Case 5
if (de == 0)
{
// SubCase 1
if (c1.r == c2.r)
{
min = 0;
max = 0;
}
// Subcase 2
else if (c1.r - c2.r > 0)
{
min = c1.r - c2.r;
max = min + 2 * c2.r;
}
else
{
min = c2.r - c1.r;
max = min + 2 * c1.r;
}
}
// Case 1
else if (de >= c1.r + c2.r)
{
min = de - c1.r - c2.r;
max = de + c1.r + c2.r;
}
// Case 3
else if (de + c2.r < c1.r)
{
max = c2.r + c1.r + de;
min = c1.r - de - c2.r;
}
// Case 4
else if (de + c1.r < c2.r)
{
max = c2.r + c1.r + de;
min = c2.r - de - c1.r;
}
// Case 2
else if ((de + c2.r >= c1.r) || (de + c1.r >= c2.r))
{
max = c2.r + c1.r + de;
min = 0;
}
// Since value of k will always be an integer
long temin = (long) (Math.ceil(min));
long re = (long) max;
if (k >= temin && k <= re)
{
return true;
}
return false;
}
// Driver Code
public static void main(String[] args)
{
node circle1 = new node();
node circle2 = new node();
int k = 3;
circle1.x = 0;
circle1.y = 0;
circle1.r = 5;
circle2.x = 8;
circle2.y = 3;
circle2.r = 2;
if (check(circle1, circle2, k))
{
System.out.println("Yes");
}
else
{
System.out.println("No");
}
}
}
// This code is contributed by Princi Singh
Python
# Python3 program to implement above approach
from math import sqrt,ceil,floor
# Return distance between the centers
def dis(x1, y1, x2, y2):
return sqrt((x1 - x2) * (x1 - x2) +
(y1 - y2) * (y1 - y2))
def check(c1, c2, k):
min = 0
max = 0
# Distance between centers
de = dis(c1[0], c1[1], c2[0], c2[1])
# Case 5
if (de == 0):
# SubCase 1
if (c1[2] == c2[2]):
min = 0
max = 0
# Subcase 2
else:
if (c1[2] - c2[2] > 0):
min = c1[2] - c2[2]
max = min + 2 * c2[2]
else:
min = c2[2] - c1[2]
max = min + 2 * c1[2]
# Case 1
elif (de >= c1[2] + c2[2]):
min = de - c1[2] - c2[2]
max = de + c1[2] + c2[2]
# Case 3
elif (de + c2[2] < c1[2]):
max = c2[2] + c1[2] + de
min = c1[2] - de - c2[2]
# Case 4
elif (de + c1[2] < c2[2]):
max = c2[2] + c1[2] + de
min = c2[2] - de - c1[2]
# Case 2
elif ((de + c2[2] >= c1[2]) or (de + c1[2] >= c2[2])):
max = c2[2] + c1[2] + de
min = 0
# Since value of k wialways be an integer
temin = ceil(min)
re = max
if (k >= temin and k <= re):
return True
return False
# Driver Code
circle1 = [0, 0, 5]
circle2 = [8, 3, 2]
k = 3
if (check(circle1, circle2, k)):
print("YES")
else:
print("NO" )
# This code is contributed by mohit kumar 29
C#
// C# program to implement above approach
using System;
class GFG
{
public class node
{
public long x, y, r;
};
// Return distance between the centers
static long dis(long x1, long y1, long x2, long y2)
{
return (long) Math.Sqrt((x1 - x2) * (x1 - x2)
+ (y1 - y2) * (y1 - y2));
}
static Boolean check(node c1, node c2, int k)
{
long min = 0;
long max = 0;
// Distance between centers
long de = dis(c1.x, c1.y, c2.x, c2.y);
// Case 5
if (de == 0)
{
// SubCase 1
if (c1.r == c2.r)
{
min = 0;
max = 0;
}
// Subcase 2
else if (c1.r - c2.r > 0)
{
min = c1.r - c2.r;
max = min + 2 * c2.r;
}
else
{
min = c2.r - c1.r;
max = min + 2 * c1.r;
}
}
// Case 1
else if (de >= c1.r + c2.r)
{
min = de - c1.r - c2.r;
max = de + c1.r + c2.r;
}
// Case 3
else if (de + c2.r < c1.r)
{
max = c2.r + c1.r + de;
min = c1.r - de - c2.r;
}
// Case 4
else if (de + c1.r < c2.r)
{
max = c2.r + c1.r + de;
min = c2.r - de - c1.r;
}
// Case 2
else if ((de + c2.r >= c1.r) || (de + c1.r >= c2.r))
{
max = c2.r + c1.r + de;
min = 0;
}
// Since value of k will always be an integer
long temin = (long) (Math.Ceiling((double)min));
long re = (long) max;
if (k >= temin && k <= re)
{
return true;
}
return false;
}
// Driver Code
public static void Main(String[] args)
{
node circle1 = new node();
node circle2 = new node();
int k = 3;
circle1.x = 0;
circle1.y = 0;
circle1.r = 5;
circle2.x = 8;
circle2.y = 3;
circle2.r = 2;
if (check(circle1, circle2, k))
{
Console.WriteLine("Yes");
}
else
{
Console.WriteLine("No");
}
}
}
// This code contributed by Rajput-Ji
Javascript
输出:
YES