编程任务:子矩阵之和

Posted

技术标签:

【中文标题】编程任务:子矩阵之和【英文标题】:Programming task: sum of submatrices 【发布时间】:2014-12-21 12:43:16 【问题描述】:

我在解决我的编程任务时遇到了问题。事实上,我解决了它,但我的代码没有通过一些测试(时间监督)。

任务正文如下: 我们有一个大小为N*N 的矩阵。输入的第一行包含两个 int:N 和 K。K 是定义子矩阵的行数。 接下来N 行包含主矩阵的元素(空白作为元素的分隔符,\n 作为行的分隔符)。之后,我们有 K 行定义子矩阵。

定义如下y_l x_l y_r x_r 其中(x_l, y_l) 是主矩阵中子矩阵左上角的列和行,(x_r, y_r) 是右下角的列和行子矩阵。我们必须计算所有子矩阵的总和并将其划分为等价类(如果总和相等,则子矩阵属于一个类)。

程序的输出应如下: 三个整数(除以空格),其中第一个是等价类的数量,第二个是具有最大元素的等价类的数量,第三个是所有子矩阵之和的平均值。

从测试中我发现问题在于总和的计算:

while(true)
    for(int i = x_l; i <= x_r; i++)
        sum += *diff++;
    if(diff == d_end) break;
    d_start = d_start + size;
    diff = d_start;

但我不知道如何优化它。可能有人可以给我算法或一些想法如何更快地计算这些总和。 谢谢。

更新:回答 经过几天的搜索,我终于得到了我的程序的工作版本。感谢 Yakk,它提供了一些非常有用的建议。 最后还有code. 非常有用的链接,除非我问一个非常具体的问题(基于 Yakk 给我的信息)link. 我希望我的代码将来可能对某人有所帮助。

【问题讨论】:

【参考方案1】:

建立一个求和矩阵。

在求和矩阵中的位置(a,b)处,将原矩阵中(a,b)的左上方(包括(a,b)处)所有元素的和相加。

现在计算子矩阵的总和是 4 次查找,一次加法和两次减法。绘制一个 4x4 矩阵并使用这些和来表示右下角的 2x2,看看如何。

如果您将存储的数据翻倍,则可以将查找次数减半。但我不会打扰。

如果您仔细操作,构建和矩阵只需要少量的工作。

【讨论】:

好的,知道了。我想过这样的事情,但它似乎有更大的内存复杂性。无论如何,既然我别无选择,我会尝试以这种方式实现。谢谢。 @llya 您可以存储它而不是原始输入矩阵。只需从每一行的左侧累积并添加上面的条目。除非溢出,没有损失。但是,我会在第二次通过时这样做:KISS 并在它工作后进行优化。 哦,我不是这么想的。我会记住的,谢谢你的解释。

以上是关于编程任务:子矩阵之和的主要内容,如果未能解决你的问题,请参考以下文章

2014子矩阵

子矩阵(NOIP2014 普及组第四题)

关于编程思路

算法211动态规划的引入 ——最大子矩阵(来自北京大学POJ)

[LintCode] Submatrix Sum 子矩阵之和

java并发编程实战