ACM二哥种花生问题

问题

Description

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

Input Format

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

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

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

Output Format

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

Sample Input

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

Sample Output

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。


解答

思路

网上有比较牛的思路,大家可以自行搜索,我的思路是按照题意进行遍历搜索,但由于优化的好依然可以满分通过。

思路就是把选取的块撕成竖条,并且将值存入tmp[]数据,这样横向每个块的值就是上一个块减去第一个竖条的值,然后加上后一个竖条的值。横向匹配完毕后,竖向下移一格,此时每个竖条的值为tmp[]减去上面那个数字,再加上下面那个数字。

#include 
using namespace std;

int a,b;
int juxing[1000][1000];
int tmp[1000];

/**
 *计算选取的一竖列的和
 */
int jisuanv(int v, int h)
{
    int num = 0;
    //如果不是第一行,则取出上行中缓存的竖列的值减去上面那个数,加上下面那个数字。
    if(h>0)
    {
        num = tmp[v] - juxing[h-1][v] + juxing[a+h-1][v];
        return num;
    }
    //如果是第一行,那么就只能相加了。
    for(int i = h; i < a+h; i++)    
    {
        num = num + juxing[i][v];
    }   
    return num;     
}

int main( int argc, char *argv[])
{

    int L,W;
    int max=0; 
    cin>>L>>W;
    int body=0;
    for(int i = 0; i < L ; i++)
    {
        for(int j = 0; j < W; j++)
        {
            cin>>juxing[i][j];
        }   
    }

    cin>>a>>b;
    for(int i = 0; i <= L - a; i++)
    {
        body = 0;   
        //前b列相加作为body,然后从body中减去第一列,加上后一列,就是每个body的值。
        for(int m = 0; m < b; m++)
        {
            tmp[m] = jisuanv(m,i);
            body = body + tmp[m];
        }

        if(body > max) {
            max = body;
        }
        for(int j = b; j < W; j++)
        {   
            tmp[j] = jisuanv(j,i);  
            body = body + tmp[j] - tmp[j-b];

            if(body > max)
            {
                max = body;
            }
        }
    }   

    cout<return 0;
}

结果(来自上海交通大学ACM题库测试)

运行编号 提交者 题目编号 评测结果 分数 时间 内存 语言 提交时间
277080 李** 1002 正确 100 2836ms 59392kb C++ 2016-04-06

你可能感兴趣的:(二哥种花生,acm,ACM)