【问题标题】:Max possible square paint brush to paint a canvas画布的最大可能方形画笔
【发布时间】:2015-10-15 18:18:57
【问题描述】:

有一个问题在采访中问过我。问题陈述如下:- 有一个画家和一个 NxM 网格画布。 Painter 有任何正方形大小的画笔,即任何 nxn 大小。 Painter 知道他需要绘制哪些网格块,哪些必须留白(Painter 打算绘制黄色和白色的绘画)。因此,任何网格块都应为黄色或白色。除此之外,还有一些不关心的块,它们要么涂成黄色,要么留白。现在,我们必须提出一种算法,以尽量减少画家的工作量,并告诉最大可能的 nxn 画笔可用于绘制画布。 示例:-

Sample canvas of 8x4 Grid. Yellow color block has to paint,white color block has to left white and blue color block are don't care blocks can either be white or painted

如上例所示,最大尺寸为 2x2 的画笔可用于成功绘制画布。

我建议使用蛮力解决方案,即检查每种颜色并决定哪种颜色可以覆盖最大可能的方形画笔。面试官对此解决方案不满意。 我想问一下:- 1)解决这个问题的最佳方法是什么。 2) 这可以用动态规划的概念来解决吗?

【问题讨论】:

  • 我想到的第一个优化 - 从画笔大小min(gridweight, gridheight) / 2 开始并尝试绘制所有内容,如果这个画笔可以绘制所有内容 - 增加画笔大小,否则减小,就像你在二进制搜索中所做的那样
  • 每个黄色字段找到包含它的最大黄蓝色方块就足够了。这些正方形的最小尺寸是一个解决方案。
  • 请整理Painter intent to paint a Yellow …don't care blocks which either be painted with black color or …
  • @greybeard 画家将使用一种颜色(即这里的黄色)进行绘画......无论如何,谢谢指出。

标签: algorithm data-structures dynamic-programming


【解决方案1】:

让我们用A 表示min(N,M)。这个问题可以在O(A^2 N M Log A)用一个简单的解决方案来解决。还有一个复杂的解决方案O(N M Log A)

重要观察

如果可以用K x K 刷子给板子上色,那么绝对可以用任何更小的刷子给板子上色。因此我们可以通过二分查找来解决这个问题。

解决方案暂存

int left = 1, right = min(N, M) + 1;
while (right - left > 1) {
  int middle = (left + right) / 2;
  if (PossibleToColor(middle)) {
    left = middle;
  } else {
    right = middle;
  }
}
OutputAnswer(left);

简单解决方案和复杂解决方案的提示

剩下的唯一棘手的事情是如何实现PossibleToColor(int K)

简单的解决方案只是迭代画笔的每个可能位置。如果这个位置的画笔下没有白色的单元格,我们需要绘制画笔下的所有单元格。检查完所有位置后,我们需要检查每个黄色单元格是否都已绘制。 PossibleToColor 的每次调用都将在 O(K^2NM) 中运行,因此 O(A^2 N M Log A) 的总运行时间。

在复杂的解决方案中,您需要构建一个整数矩阵NxM。当且仅当画布的相应像素为白色时,它的元素才等于 1,否则等于 0。然后您需要遍历所有画笔位置并检查我们是否可以在此处放置画笔(您需要计算子正方形上的总和,如果是正数,则不能)。要快速做到这一点,您需要使用数据结构来计算O(1) 中整数矩阵的子矩形中的数字总和。在O(NM)中构建这样的数据结构是可能的。

那么在你找到所有可能的画笔位置后,你需要再构建一个整数矩阵NxM。当且仅当该元素中存在带有左上角的画笔位置时,其元素等于 1,否则等于 0。然后您需要遍历每个黄色像素并检查它是否会被画笔的至少一个可能位置绘制。要检查您是否需要在所述矩阵的子矩形中计算总和。您需要使用相同的数据结构。

所描述的整数矩阵A的数据结构只是一个矩阵S,这样

S[i][j] = A[p][q] 之和使得1 <= p <= i, 1 <= p <= j

它可以通过O(NM) 中的简单动态规划来计算。当您计算它时,子矩形i1 <= i <= i2, j1 <= j <= j2 中的总和可以计算为

S[i2][j2] - S[i2][j1 - 1] - S[i1 - 1][j2] + S[i1 - 1][j1 - 1].

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-09
    • 1970-01-01
    • 1970-01-01
    • 2012-10-16
    • 2015-05-11
    • 1970-01-01
    • 1970-01-01
    • 2018-08-13
    相关资源
    最近更新 更多