📜  需要删除最小圆圈,以便所有剩余的圆圈不相交

📅  最后修改于: 2021-10-26 06:27:06             🧑  作者: Mango

假设在 xy 平面中存在 n 个圆,使得所有圆的中心都在 x 轴上对齐。
任务是移除其中的一些,使得没有两个圆相交。找出需要删除的最小圆圈数。

注意:接触圆也被认为是相交的。
给定 N 和一对整数数组。每对包含两个整数 c 和 r,分别表示半径为 r 且中心为 (c, 0) 的圆。

例子:

方法:
可以应用贪心策略来解决问题。

  • 找出圆直径的起点和终点。
  • 起点等于 (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 现场工作专业课程学生竞争性编程现场课程