输入:区域(0,0)到(1600,1200)内的一组矩形。
输出:没有任何矩形包含的点。
什么是有效的算法?我目前唯一能想到的两个是:
为什么我这样做?这不是用于家庭作业或编程比赛,虽然我认为这个问题的一个更复杂的版本被问到一个(每个矩形都有一个'颜色',你必须输出他们给你的几个点的颜色)。我只是试图以编程方式在Windows上禁用第二台显示器,而我遇到了更多sane approach的问题。所以我的目标是在桌面上找到一个未占用的位置,然后模拟右键单击,然后模拟从显示属性窗口禁用它所需的所有点击。
答案 0 :(得分:4)
对于每个矩形,创建沿水平方向的运行列表。例如,一个100x50的矩形将生成50次100次运行。用最左边的X坐标和Y坐标将它们写入列表或地图。
对列表进行排序,首先是Y,然后是X.
浏览列表。重叠运行应该是相邻的,因此您可以合并它们。
当你发现第一次没有在整个屏幕上延伸时,你已经完成了。
答案 1 :(得分:3)
Region
)。它们是为此而发明的。但这不是语言无关的。P.S。:考虑针对最大化窗口进行优化。然后你就可以看出没有命中测试就没有像素可见。
答案 2 :(得分:3)
注意:假设矩形在形式上:(x1,y1,x2,y2),表示所有点(x,y),使得x1 <= x&lt; x2&amp;&amp; y1&lt; = y&lt; Y2
Nore2:Xi&amp; Yj可以存储在排序的数组或树中以进行O(log n)访问。如果矩形的数量很大。
答案 3 :(得分:1)
如果您知道矩形的最小x和y尺寸,则可以使用较少的像素来使用第一种方法(布尔数组的2D数组)。
考虑到1600x1200小于2M像素。真的那么多记忆吗?如果你使用位向量,你只需要235k。
答案 4 :(得分:1)
你的第一个想法并不是那么糟糕......你应该只改变数据的表示。 你可能会对布尔的稀疏数组感兴趣。
依赖于语言的解决方案是使用Area (Java)。
答案 5 :(得分:1)
如果我必须自己这样做,我可能会选择2d阵列的布尔值(特别是按照jdv建议缩小,或使用加速图形例程)或随机点方法。
如果你真的想做一个更聪明的方法,你可以考虑矩形。从带有角(0,0),(1600,1200)=(lx,ly),(rx,ry)的矩形开始,并“减去”第一个窗口(wx1,wy1)(wx2,wy2)。
如果它完全包含在原始的自由矩形内,则最多可以生成4个新的“仍然可用”矩形:(例如,新窗口的所有4个角都包含在旧窗口中)它们是(lx,ly) - (rx,wy1),(lx,wy1) - (wx1,wy2),(wx2,wy1) - (rx,wy2)和(lx,wy2) - (rx,ry)。如果窗口的一个角落重叠(只有一个角落在自由矩形内),它会将其分成两个新的矩形;如果一侧(2个角)伸入其中则将其分成3个;如果没有重叠,没有任何改变。 (如果它们都是轴对齐的,则内部不能有3个角。)
然后继续循环浏览窗口,测试交集和子划分矩形,直到你有一个矩形方面的所有剩余可用空间的列表(如果有的话)。
这可能会比上面的任何图形库驱动的方法慢,但写起来会更有趣:)
答案 6 :(得分:1)
这不取决于您所在区域的像素数,因此适用于大(或无限)分辨率。未覆盖列表中的每个新矩形将在其他矩形对的唯一交叉点处具有角,因此列表中最多将有O(n ^ 2),总运行时间为O(n ^ 3)。您可以通过将未覆盖的矩形列表保持为更好的结构来检查每个覆盖矩形,从而提高效率。
答案 7 :(得分:0)
这是一个仅1600 + 1200空间复杂度的简单解决方案,它在概念上类似于创建1600x1200矩阵但不使用整个矩阵: