在采访中有一个问题要求我。问题陈述如下: - 有一个画家,有一个NxM网格画布。画家有任何方形尺寸的油漆刷,即任何nxn尺寸。画家知道他需要绘制哪些网格块,哪些必须留白(Painter意图绘制黄色和白色绘画)。因此,任何网格块都应该是黄色或白色。除此之外,还有一些不关心的护理块可以涂上黄色或留白色。现在,我们必须提出一种算法,以尽量减少画家的努力,并告诉最大可能的nxn画笔,可以用来画画布。 示例: -
如上例所示,最大尺寸为2x2画笔可用于成功绘制画布。
我建议使用强力解决方案,即检查每种颜色,并确定哪种颜色将覆盖最大可能的方形刷。访问者对此解决方案并不满意。 我想问一下:- 1)解决这个问题的最佳方法是什么。 2)可以使用动态编程概念解决这个问题。
答案 0 :(得分:1)
我们用A
表示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
总运行时间。
在复杂的解决方案中,您需要构建一个整数矩阵O(1)
。当且仅当画布的相应像素为白色时,其元素相等,否则它等于零。然后你需要迭代所有画笔位置并检查我们是否可以在这里画一个画笔(你需要在子广场上计算一个和,如果它是正数,那么你不能)。要快速完成,您需要使用数据结构来计算O(NM)
中整数矩阵的子矩形中的数字总和。可以在NxM
中构建此类数据结构。
然后在找到画笔的所有可能位置后,需要再构建一个整数矩阵A
。当且仅当在该元素中存在具有左上角的画笔位置时,其元素等于1,否则它等于零。然后你需要迭代每个黄色像素并检查它是否会被刷子的至少一个可能位置绘制。要检查是否需要在所描述的矩阵上计算子矩形中的和。您需要使用相同的数据结构。
所描述的整数矩阵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]
中的总和可以计算为
{{1}}。