如何在2D数组中找到给定范围的最大总和?

时间:2015-04-06 05:05:56

标签: c

  

我需要知道如何在2D数组中找到给定范围的最大总和,最好是在C中,以提高下面给出的代码效率并解决问题。

为了更好地理解这一点,请阅读下面我需要解决的问题。

问题

  

大城市X是N行和M列的网格。有给出   生活在每个细胞中的人数。你被要求定位   电信塔让人们满意。该   蜂窝塔可以覆盖Y行和X列的矩形区域。   找到您可以满足的最大人数。

约束

1 <= N, M <= 1000
1 <= Y <= N, 1 <= X <= M
1 <= number of people in a cell <= 1000

细胞塔覆盖的矩形区域不应部分覆盖任何细胞。

输入

输入的第一行将包含4个数字N,M,Y和X,分别用空格分隔。接下来的N行中的每一行都包含第1行到第N行的整数。每行将M个整数,表示每个单元格中居住的人数由空格分隔。

输出

输出应该只包含一个整数,即您可以满足的最大人数。

示例输入

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

示例输出

38

解释

通过将塔覆盖2x3区域(包括5,6,7,2,9和9个单元格),可以满足最大人数。

5 + 6 + 7 + 2 + 9 + 9 = 38

我的代码

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>

int main() {

int N, M, Y, X;
scanf("%d %d %d %d", &N, &M, &Y, &X);

int max = 0;
int total = 0;

int data[N][M];

for(int i = 0; i < N; i++)
    for(int j = 0; j < M; j++)
        scanf("%d",&(data[i][j]));    

for(int i = 0; i < N; i++)
{
    for(int j = 0; j < M; j++)
    {
        total = 0;

            for(int l = 0; (l < Y) && (i + Y) <= N; l++)
            {

                for(int k = 0; (k < X) && (j + X <= M); k++)
                {
                    total += data[i+l][j+k];
                }

                if(total > max)
                    max = total;                       
        } 
    }  
}   

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

此代码失败,因为它过于线性,并且在使用较大输入时需要花费大量时间。

您可以自己尝试解决问题,here

1 个答案:

答案 0 :(得分:0)

我认为你的数字网格问题解决方案中的主要问题是嵌套的for循环。最简单的优化是最小化范围内每次移动的重新计算次数。

我在原始代码中尝试了以下更改:

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>

int main() {

    int N, M, Y, X;
    scanf("%d %d %d %d", &N, &M, &Y, &X);

    int max = 0;
    int total = 0;

    int data[N][M];

    for(int i = 0; i < N; i++)
        for(int j = 0; j < M; j++)
            scanf("%d",&(data[i][j]));  
     ////////////////////////////////////////////////////////////
    // calculation of the first total and initial max
    int startTotal = 0;
    int r, c;
    for(r = 0; r < Y-1; r++)
    {
        for(c = 0; c < X-1; c++)
        {
            startTotal += data[r][c];
        }
    }
    max = startTotal;

    for(int i = 0; i+Y <= N; i++)
    {
        // add next line
        for(int c = 0; c < X-1; c++)
        {
            startTotal += data[i+Y-1][c];
        }
        total = startTotal;
        for(int j = 0; j+X <= M; j++)
        {
            // add next column
            for(int r = i; r < i+Y; r++)
                total += data[r][j+X-1];
            // compare
            if(total > max)
            {
                max = total;
            }
            // subtract the first column
            for(int r = i; r < i+Y; r++)
                total -= data[r][j];
        }
        // subtract the first line
        for(int c = 0; c < X-1; c++)
        {
            startTotal -= data[i][c];
        }
    }
    ////////////////////////////////////////////////////////
    printf("%d",max);
    return 0;
}

我已尝试在hackerrank.com上运行该程序,并已收到

enter image description here

相关问题