假设在 xy 平面中存在 n 个圆,使得所有圆的中心都在 x 轴上对齐。
任务是移除其中的一些,使得没有两个圆相交。找出需要删除的最小圆圈数。
注意:接触圆也被认为是相交的。
给定 N 和一对整数数组。每对包含两个整数 c 和 r,分别表示半径为 r 且中心为 (c, 0) 的圆。
例子:
Input : N=4, arr={(1, 1), (2, 1), (3, 1), (4, 1)}
Output : 2
Remove 2nd and 3rd circle to make the circles non-intersecting.
Input : N=4, arr={(1, 1), (4, 1), (5, 2), (7, 1)}
Output : 1
方法:
可以应用贪心策略来解决问题。
- 找出圆直径的起点和终点。
- 起点等于 (cr),终点等于 (c+r),其中 (c, 0) 是特定圆的中心,r 是其半径。
- 根据结束点的值对 {start, end} 对进行排序。端点的值越小,它的指数就越小。
- 开始迭代这些对,如果圆的起点小于当前的结束值,则意味着圆相交,因此增加计数。否则更新当前的结束值。
下面是上述方法的实现:
C++
// C++ implementation of the above approach
#include
#include
using namespace std;
struct circle {
int start, end;
};
// Comparison function modified
// according to the end value
bool comp(circle a, circle b)
{
if (a.end == b.end)
return a.start < b.start;
return a.end < b.end;
}
// Function to return the count
// of non intersecting circles
void CountCircles(int c[], int r[], int n)
{
// structure with start and
// end of diameter of circles
circle diameter[n];
for (int i = 0; i < n; ++i) {
diameter[i].start = c[i] - r[i];
diameter[i].end = c[i] + r[i];
}
// sorting with smallest finish time first
sort(diameter, diameter + n, comp);
// count stores number of
// circles to be removed
int count = 0;
// cur stores ending of first circle
int cur = diameter[0].end;
for (int i = 1; i < n; ++i) {
// non intersecting circles
if (diameter[i].start > cur) {
cur = diameter[i].end;
}
// intersecting circles
else
count++;
}
cout << count << "\n";
}
// Driver Code
int main()
{
// centers of circles
int c[] = { 1, 2, 3, 4 };
// radius of circles
int r[] = { 1, 1, 1, 1 };
// number of circles
int n = sizeof(c) / sizeof(int);
CountCircles(c, r, n);
return 0;
}
Java
// Java implementation of the above approach
import java.util.Arrays;
import java.util.Comparator;
public class MinimumCirclesTobeRemoved {
private class Circle implements Comparator{
int start;
int end;
// Comparison function modified
// according to the end value
public int compare(Circle a , Circle b){
if(a.end == b.end){
return (a.start - b.start);
}
return a.end - b.end;
}
}
// Function to return the count
// of non intersecting circles
public void CountCircles(int[] c, int[] r, int n){
// structure with start and
// end of diameter of circles
Circle diameter[] = new Circle[n];
for(int i = 0; i < n; i++)
{
diameter[i] = new Circle();
diameter[i].start = (c[i] - r[i]);
diameter[i].end = (c[i] + r[i]);
}
// sorting with smallest finish time first
Arrays.sort(diameter, new Circle());
// count stores number of
// circles to be removed
int count = 0;
// cur stores ending of first circle
int curr = diameter[0].end;
for(int i = 1; i < n; i++)
{
// non intersecting circles
if(diameter[i].start > curr)
{
curr = diameter[i].end;
}
else
{
count++;
}
}
System.out.println(count);
}
// Driver code
public static void main(String[] args)
{
MinimumCirclesTobeRemoved a = new MinimumCirclesTobeRemoved();
// centers of circles
int[] c = new int[]{1, 2, 3, 4};
// radius of circles
int[] r = new int[]{1, 1, 1, 1};
a.CountCircles(c, r, c.length);
}
}
// This code is contributed by parshavnahta97
Python3
# Python3 implementation of the above approach
# Function to return the count
# of non intersecting circles
def CountCircles(c, r, n):
# Structure with start and
# end of diameter of circles
diameter = []
for i in range(n):
obj = []
obj.append(c[i] - r[i])
obj.append(c[i] + r[i])
diameter.append(obj)
# Sorting with smallest finish time first
diameter.sort()
# count stores number of
# circles to be removed
count = 0
# cur stores ending of first circle
cur = diameter[0][1]
for i in range(1, n):
# Non intersecting circles
if (diameter[i][0] > cur):
cur = diameter[i][1]
# Intersecting circles
else:
count += 1
print(count)
# Driver Code
# Centers of circles
c = [ 1, 2, 3, 4 ]
# Radius of circles
r = [ 1, 1, 1, 1 ]
# Number of circles
n = len(c)
CountCircles(c, r, n)
# This code is contributed by rohitsingh07052
输出:
2
时间复杂度: O(N*log(N))
其中 N 是圈数。
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。