给定一个矩形区域和一组矩形,检查它们是否覆盖了整个区域

Given a rectangular area and a set of rectangles, check if the entire area is covered by them

本文关键字:区域 是否 检查 覆盖 一个 一组      更新时间:2023-10-16

这里所有的值都是实数,最多两个浮点数

假设我们有一个矩形面积,100.0 × 75.0

然后给你一组矩形。如何检查这些矩形合起来是否覆盖了整个面积?

如果我们有

(0,0,50,75)

显然这不会发生,因为它只覆盖了一半的区域。如果我们有

(0,0,50,75)
(50,0,50,75)

那么这是有效的,因为两个矩形将有效地覆盖整个(100,75)

What have I try

I 尝试(没有成功)创建一个多维布尔值数组:

bool area[10000][7500];

这些是面积的尺寸,乘以100,这样我就不用处理浮点数了。然后我只是迭代我的每个矩形(它们的值也乘以100),并且对于它们中的每个"像素",我将布尔值转换为true

最后,我检查该区域的所有布尔值是否都是true

这被证明是非常愚蠢的。你能帮我找个更好的方法吗?

我认为这样的策略会奏效:

  1. 扔掉任何完全在你的区域之外的矩形
  2. 沿着列表中矩形的边缘相对于一个轴将你的区域分割成更小的矩形
  3. 将在步骤2中创建的区域矩形列表沿着覆盖列表中矩形的边缘相对于另一个轴分割
  4. 你现在有两个矩形列表,其中必须有一个在覆盖列表中完全覆盖每个区域矩形

我相信你的"位图"尝试失败是因为(通常的)浮点舍入问题。不幸的是,你对此无能为力。

对于正确的算法,我将使用减法技术来接近它。

    让我们把你的初始矩形集合命名为r。
  • 初始化第二组矩形S,初始包含一个覆盖整个区域的矩形。
  • 对于R中的每个矩形:
    • 对于S中的每个矩形:
      • 如果两个R和S矩形相交,用尽可能多的矩形替换S矩形(如果我没弄错的话,0到4),覆盖S矩形左侧的非相交部分。
      • 继续迭代S,注意不要为你刚刚添加的新S矩形计算任何东西(我们已经知道它不与当前R矩形相交)。
    • 继续在R上迭代,这次考虑新的S个矩形,直到:
      • 在S中没有矩形,在这种情况下你的R矩形覆盖了整个区域。
      • 或者,你迭代了所有R个矩形,仍然有S个矩形,在这种情况下,你的R个矩形不覆盖整个区域。

至于复杂性,我不确定它与@500-Internal-Server-Error或@Tommy的解决方案相比如何,但嘿,至少我设法想出了一些东西,当我一开始读到你的问题时,我认为我不能——我通常不太擅长空间问题。:)

在概念上与500 - Internal Server Error's非常相似,可以避免最后一步隐含的O(n^2)搜索:

  1. 建立覆盖集中每个矩形的垂直边界列表;
  2. 假设有n个边界,你在源矩形上有n+1条垂线要考虑;
  3. 对于每个条带,获得与它重叠的所有矩形的列表(你可以在O(n)时间内做到这一点,从矩形推到箱子而不是向后搜索);
  4. 从左到右排序(即O(n log n));
  5. 遍历排序列表,并尝试找到一个间隔,其中一个跨度结束,直到稍后才开始其他任何内容(另一个O(n)任务)。

如果你找到一个合适的缺口,那么原来的不被覆盖。如果你不这样做,那么它就是。顺便说一下,这就是span缓冲的工作原理