遍历二维数组的所有子数组

时间:2018-10-13 10:15:28

标签: c++ arrays loops dynamic-programming sub-array

我有一个二维数组,大小为P * Q,我必须根据该数组回答K个问题。给定的二维数组由数字0和1组成。对于每个问题,我们必须计算没有两个相同元素相邻的任何正方形子数组的最大大小。 例如,如果P = Q = 8且给定数组为

00101010
00010101
10101010
01010101
10101010
01010101
10101010
01010101

然后,问题Ki使我们能够进行Ki的翻转次数(从0到1或从1到0。)

Here K=4(number of questions)
1 2 0 10001
Output: 7 8 6 8

我了解到,对于K1 = 1,我们可以将数组index(1,1)的值更改为1,并获得7 * 7大小的有效矩阵,输出为7。如果我们有Ki> = 2我们的答案将是8。 我认为,我们必须维护一个数组ans [k],该数组存储有效的正方形子矩阵的最大大小。为此,我们可以从原始数组的每个索引开始,遍历其子数组,如果从该索引开始,则可以计算flip = i的最大大小值。我们必须对从每个索引开始的子数组执行此操作,然后将它们的最大值存储在flip [i]中。 我不知道如何遍历给定索引的所有子数组,因此在实现此方法时遇到了问题。我已经尝试了很长时间,但仍然没有实现。谁能帮忙吗?

1 个答案:

答案 0 :(得分:0)

它有助于简化问题,使其仅依赖于单个值(而不是成对的相邻值)。因此,将 XOR 与每个完美棋盘格进行网格化:

01111111  10000000
10111111  01000000
11111111  00000000
11111111  00000000
11111111  00000000
11111111  00000000
11111111  00000000
11111111  00000000

现在的目标是在两个 网格中找到最大不超过 K_i 0s的正方形(显然,这里偏左)。

K_i = 0开头。要找到1的最大正方形,请为每个单元格计算从其开始的中的1的数目(0表示一个包含0的单元格;然后以该单元格为左上角的最大正方形(假设其为1)比其右邻居(该列)的行长度的最小多一个。下邻居的长度以及右下邻居的平方大小。 (对于网格外部不存在的单元格,所有这些均为0。)访问 diagonal-major 的单元格,以便在需要时可以使用这些值;请注意产生的最大正方形尺寸。

要归纳为 K_i > 0,请为每个单元格存储这三个值(行长,列长和正方形大小),以每次翻转次数直到< em> K_i 。像元一样为1的单元格会像以前一样向每行/列长度加1,而像元长度为0的单元格将移位到下一个翻转计数,舍弃那些其翻转计数的单元格现在太大了,并且在0次翻转时添加了新值 0。对于行长向东,列长南向和方格东南的每种组合(每个都有翻转计数),单元格将得到一个候选方格,这是其最小值,< em> sum 的翻转计数,如果单元格本身为0,则加1 。对于每个翻转计数(不是太大),请保持最大的正方形大小,并注意它是否是迄今为止遇到的最大(对于该翻转计数)。

请注意,当平方比数组小得多时,蛮力解决方案的速度可能几乎一样快,因为它只需访问几次即可。