Logo 贾永菁的博客

博客

C 套圈题解

2022-05-10 19:34:35 By 贾永菁

为了这题 我们首先要了解什么是前缀数组

前缀和

前缀和是一种重要的预处理,能大大降低查询的时间复杂度。可以简单理解为“数列的前n项的和”。

C++ 标准库中实现了前缀和函数 std::partial_sum,定义于头文件 中。

以上内容来自传送门

有兴趣者自便

举个例子

1 2 4 3

5 1 2 4

6 3 5 9

这个数组的前缀数组长这样

1 3 7 10

6 9 15 22

12 18 29 45

这是怎么推的呢,有公式

a[i][j]=a[i-1][j]+a[i][j-1]+a[i-1][j-1];

了解什么是前缀和数组后,开始思路

我们如果把样例数据列出来

可以得到下表

0 0 0 0 1 0 0

0 0 1 0 0 0 0

0 0 0 1 0 0 0

0 0 0 0 0 1 0

0 0 0 0 0 0 1

0 0 0 0 0 0 0

0 0 0 1 0 0 0

0 0 0 0 0 0 0

0 1 0 0 0 0 0

0 0 0 1 0 1 0

0 0 0 1 0 0 0

可以看出是以(1,4)(1,6)(11,4)(11,6)为顶点的长方形和最大(下标从1开始)

那么有一位机智的同学提出问题

小贾,小贾,这和你刚说了一大堆的前缀数组有什么关系?

好,问题提的好,(下次别提了)。

我们来看,如果把刚提到的长方型为一个部分,长方形中的空心为第二部分

你发现了什么?

用前缀数组是不能直接求长方形一圈的和,但可以求整个长方形的和与中间空心的和

两者相减就得出答案

那么只要枚举长方形左上角,右下角的点就可求出最大和

至于为什么可以枚举,因为数据只有100!!

只贴核心代码

for(int i=1;i<=100;i++)

    for(int j=1;j<=100;j++)

        sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[i][j];

计算前缀和

a[i][j]为输入数组

sum为前缀和数组

剩下的只有枚举了

公式在这

/整个长方形/ int j=sum[x2][y2]-sum[x1-1][y2]-sum[x2][y1-1]+sum[x1-1][y1-1];

/空心部分/ int k=sum[x2-1][y2-1]-sum[x1][y2-1]-sum[x2-1][y1]+sum[x1][y1];

评论

xushuoxin
好\(^o^)/~!!!【鼓掌】
MKWMA
小贾终于会markdown了!好耶ヽ(✿゚▽゚)ノ(题目讲解好b( ̄▽ ̄)d )
李冉苒
nice!!!<^o^>,真是麻雀啄了牛屁股——确(雀)实(食)牛逼!!

发表评论

可以用@mike来提到mike这个用户,mike会被高亮显示。如果你真的想打“@”这个字符,请用“@@”。