给定n个存在于xy平面中的圆,使所有圆的中心在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
输出:
2
时间复杂度: O(N * log(N))
其中N是圈数。