给出了n*m(1-基索引)的矩形网格,其中它们是k个不同单元上的k个怪物。现在我们需要回答Q查询,其中我们将给出最低行数(L)和最高行数(h)。我们需要告诉那些没有怪物的行之间的最大矩形区域(这里的矩形区域仅指单元的计数)。
例如,我们有一个4×5的网格(平均n=4和m=5),并且怪物位于7(=k)单元上,它们是(1,3),(1,4),(2,1),(2,4),(3,2),(4,1),(4,2),并且让我们有1个查询,其中L=3和H=4,然后这里的最大面积是6。
现在,如果查询非常大,比如10^6。那么如何解决这个问题。他们有什么动态的方法吗?
红色方块表示怪物,紫色方块表示解决方案矩形

最佳答案

这是一个递归的解决方案,适用于任意大小的地下城和相对较少的怪物。
如果地牢里有一个怪物(x,y)(n,w,s,e),那么就有两个例子案例1很简单:怪物在地牢外面。那么最大的矩形就是地牢。(地下城总是长方形的,对吧?)是的。
在情况2中,最大矩形是怪物的北、西、南或东的矩形之一:

NNNNNNNNNN    ....EEEEEE    ..........    WWW.......
NNNNNNNNNN    ....EEEEEE    ..........    WWW.......
NNNNNNNNNN    ....EEEEEE    ..........    WWW.......
NNNNNNNNNN    ....EEEEEE    ..........    WWW.......
NNNNNNNNNN    ....EEEEEE    ..........    WWW.......
...@......    ...@EEEEEE    ...@......    WWW@......
..........    ....EEEEEE    SSSSSSSSSS    WWW.......
..........    ....EEEEEE    SSSSSSSSSS    WWW.......
..........    ....EEEEEE    SSSSSSSSSS    WWW.......

现在将这个推理递归地应用到你的怪物位置列表中,并跟踪到目前为止的最大值。下面是一些伪代码:
max_area = 0
max_rect = Null

sub find_max_rect(Dungeon, Monsters)

    if area(Dunegon) <= max_area:
        return                      # save time for small dungeons

    if Monsters is empty:
        if area(Dungeon) > max:
            max_rect = Dungeon
            max_area = area(Dungeon)

    else
        M = Monsters.pop()          # Remove head from list

        if M in Dungeon:
            find_max_rect(Subrect(Dungeon, M, North), Monsters)
            find_max_rect(Subrect(Dungeon, M, East), Monsters)
            find_max_rect(Subrect(Dungeon, M, South), Monsters)
            find_max_rect(Subrect(Dungeon, M, West), Monsters)
        else:
            find_max_rect(Dungeon, Monsters)

注:实际上我在上面的草图中犯了一个明显的错误:@代表的当然是玩家而不是怪物。

08-27 15:12