1. 程式人生 > >上海交大OJ 1002. 二哥種花生(字首和法)

上海交大OJ 1002. 二哥種花生(字首和法)

1002. 二哥種花生

Description

二哥在自己的後花園裡種了一些花生,也快到了收穫的時候了。這片花生地是一個長度為L、寬度為W的矩形,每個單位面積上花生產量都是獨立的。他想知道,對於某個指定的區域大小,在這麼大的矩形區域內,花生的產量最大會是多少。

Input Format

第1行有2個整數,長度L和寬度W。

第2行至第L+1行,每行有W個整數,分別表示對應的單位面積上的花生產量A( 0≤A<10 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 1≤L,W≤100 ;

對於100%的資料: 1≤L,W≤1000 1≤L,W≤1000 。

全部區域大小滿足:1≤a≤L,1≤b≤W 1≤a≤L,1≤b≤W 。

-------演算法表格分析-------(估計只有自己能看懂)

下列程式碼使filed[i][j] 等於 以(i,j)為右下角的矩形元素的和

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

下列程式碼使t 等於 以(i,j)為右下角的大小為L * W的矩形的元素和

int t = field[i][j] - field[i - L][j] - field[i][j - W] + field[i - L][j - W];
#include <cstdio>

using namespace std;

//儲存田地
int field[1005][1005] = {0};
//儲存字首和
int pt[1005][1005] = {0};

//記錄最大值
int max = 0;

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

    //N - 田地的高 M - 田地的寬
    int N,M;

    scanf("%d%d",&N,&M);

    for(int i = 1;i <= N;i++){
        for(int j = 1;j <= M;j++){
            scanf("%d",&field[i][j]);
            //構建字首和
            field[i][j] = field[i][j] + field[i - 1][j] + field[i][j - 1] - field[i - 1][j - 1];
        }
    }

    //L 代表指定區域的高
    //W 代表指定區域的寬
    int L,W;

    scanf("%d%d",&L,&W);

    //L 和 W之後滿足區域的大小條件
    for(int i = L;i <= N;i++){
        for(int j = W;j <= M;j++){
            //減去區域外的位置
            int t = field[i][j] - field[i - L][j] - field[i][j - W] + field[i - L][j - W];

            max = max > t?max:t;
        }
    }

    printf("%d\n",max);
    return 0;
}