有趣的难题,编辑了ypercube答案中的思路:
declare @t table (x int, y int);
insert @t (x,y) values (0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2),
(2, 0), (2, 1), (2, 2), (4, 0), (4, 1), (5, 0), (5, 1);
; with all_rectangles as
(
select lt.x as x1
, lt.y as y1
, rt.x as x2
, lb.y as y2
from @t lt
join @t rt
on rt.y = lt.y
and rt.x > lt.x
join @t lb
on lb.x = lt.x
and lb.y > lt.y
join @t rb
on rb.x = rt.x
and rb.y = lb.y
)
, filled_rectangles as
(
select rect.x1
, rect.y1
, rect.x2
, rect.y2
from all_rectangles rect
join @t crossed
on crossed.x between rect.x1 and rect.x2
and crossed.y between rect.y1 and rect.y2
group by
rect.x1
, rect.y1
, rect.x2
, rect.y2
having count(*) =
(rect.x2 - rect.x1 + 1) * (rect.y2 - rect.y1 + 1)
)
select *
from filled_rectangles rect
where not exists
(
select *
from filled_rectangles bigger
where bigger.x1 <= rect.x1 and rect.x2 <= bigger.x2
and bigger.y1 <= rect.y1 and rect.y2 <= bigger.y2
and (rect.x1 <> bigger.x1 or rect.x2 <> bigger.x2
or rect.y1 <> bigger.y1 or rect.y2 <> bigger.y2)
);
首先,它会建立一个所有可能的矩形列表。然后,它要求填充位置的数量与总位置数(矩形面积)相匹配。最后,它要求没有其他完全覆盖该矩形的矩形。
你可能需要为PostgreSQL进行调整,但这个想法应该是可行的。