My Avatar

胡湘铭的博客

Coding and thinking!

SJTU 1002二哥种花生

2015年9月19日, 发表于 长春

如果你对本文有任何的建议或者疑问, 可以在 这里给我提 Issues, 谢谢! :)

SJTU 1002二哥种花生 原题地址

题目描述

二哥在自己的后花园里种了一些花生,也快到了收获的时候了。这片花生地是一个长度为L、宽度为W的矩形,每个单位面积上花生产量都是独立的。他想知道,对于某个指定的区域大小,在这么大的矩形区域内,花生的产量最大会是多少。

输入格式

第1行有2个整数,长度L和宽度W。

第2行至第L+1行,每行有W个整数,分别表示对应的单位面积上的花生产量A( 0≤A<10 )。

第L+2行有2个整数,分别是指定的区域大小的长度a和宽度b。

输出格式

输出一个整数m,表示在指定大小的区域内,花生最大产量为m。

示例输入

1
2
3
4
5
6
4 5
1 2 3 4 5
6 7 8 0 0
0 9 2 2 3
3 0 0 0 1
3 3

示例输出

1
38

样例解释

左上角:38 = (1+2+3) + (6+7+8) + (0+9+2)

数据范围

对于30%的数据: 1≤L,W≤100;

对于100%的数据: 1≤L,W≤1000。

全部区域大小满足:1≤a≤L,1≤b≤W 。 #思路一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//author:husama
#include<stdio.h>
int main()
{
    int L=0, W=0;
    int l, w,result=0,temp=0;
    scanf("%d %d",&L,&W);//输入花生地的长和宽
    int **matrix= new int*[L];  //定义矩阵数组
    for (int i = 0; i < L; ++i)  matrix[i] = new int[W];
    for (int i = 0; i < L; ++i)
    {
        for (int j = 0; j < W; ++j)
            scanf("%d",&matrix[i][j]);
    }
    scanf("%d %d",&l,&w);//获得目标区块的大小
    //遍历计算
    for (int m =0; m < W-w+1; ++m)
    {
        for (int n = 0; n< L-l+1; ++n)
        {
            temp = 0;
            for (int i = n; i < n+l; ++i)
            {
                for (int j = m; j < m+w; ++j)
                {
                    temp += matrix[i][j];
                }
            }
            if (result <= temp)result = temp;
        }
    }
    printf("%d",result);
    for (int i = 0; i < L; ++i)
        delete[]matrix[i];
    delete[] matrix;
    return 0;
}

四层for循环嵌套,时间复杂度太高,不过我还是去试了试,结果当然是超时。必须想个更简洁的算法。

思路二(改进)

所以当采用思路一的做法时,多计算了很多次! 而且,每次枚举时都要用两个for循环嵌套求出框中数字之和 怎样改进呢,我们可以改进这个矩阵的储存方式,即:

每个矩阵单元储存以1, 1为左上角,i, j为右下角的矩形内数字之和

采用这种存储方式的好处在于,如果要取得以x1, y1为左上角 x2, y2为右下角的矩形内数字之和,只需计算 matrix[x2][y2] -matrix[x1 - 1][y2] - matrix[x2][y1 - 1] + matrix[x1 - 1][y1 - 1] 即可,示意图如下: