我需要知道如何在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
答案 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上运行该程序,并已收到