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

📅  最后修改于: 2021-05-04 21:24:36             🧑  作者: Mango

给定n个存在于xy平面中的圆,使所有圆的中心在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


输出:
2

时间复杂度: O(N * log(N))
其中N是圈数。