您的位置:首页 > 其它

ACM: uva 10827 -&…

2016-05-19 23:28 295 查看
Maximum sum on a torus
A grid that wraps both horizontally and vertically is called a
torus. Given a torus where each cell contains an integer, determine
the sub-rectangle with the largest sum. The sum of a sub-rectangle
is the sum of all the elements in that rectangle. The grid below
shows a torus where the maximum sub-rectangle has been shaded.





 
 Input

The first line in the input contains the number of test cases
(at most 18). Each case starts with an integer N (1≤N≤75)
specifying the size of the torus (always square). Then follows N
lines describing the torus, each line containing N integers between
-100 and 100, inclusive.

 
Output
For each test case, output a line containing a single integer:
the maximum sum of a sub-rectangle within the torus.

 

Sample input

2

5

1 -1 0 0 -4

2 3 -2 -3 2

4 1 -1 5 0

3 -2 1 -3 2

-3 2 4 1 -4

3

1 2 3

4 5 6

7 8 9

 

Sample output

15

45

 

题意: 现在给出一个矩形的圆柱面, 每一个格子都有一个整数, 现在要你求出最大和子矩阵.

 

解题思路:

     
1. 求最大子矩阵和, 采用前缀和降维计算可以大大提高效率.

     
2. 这个问题难点是一般的最大子矩阵变成了再一个圆柱面上计算了, 不过也是没问题. 将原

     
矩阵扩大2倍即可.

     
3. ans = max( ans,
sum[i+k-1][j+p-1]-sum[i+k-1][j-1]-sum[i-1][j+p-1]+sum[i-1][j-1] );

 

代码:

#include <cstdio>

#include <iostream>

#include <cstring>

using namespace std;

#define MAX 155

const int INF = (1<<29);

int n, m;

int g[MAX][MAX], sum[MAX][MAX];

inline int max(int a, int b)

{

 return a > b ? a : b;

}

int main()

{

// freopen("input.txt", "r", stdin);

 int caseNum;

 scanf("%d", &caseNum);

 while(caseNum--)

 {

  scanf("%d",
&n);

  int i, j, k, p;

  for(i = 1; i <=
n; ++i)

  {

   for(j = 1; j
<= n; ++j)

   {

    scanf("%d",
&g[i][j]);

    g[i+n][j]
= g[i][j];

    g[i][j+n]
= g[i][j];

    g[i+n][j+n]
= g[i][j];

   }

  }

  memset(sum, 0,
sizeof(sum));

  for(i = 1; i <=
2*n; ++i)

   for(j = 1; j
<= 2*n; ++j)

    sum[i][j]
= sum[i-1][j]+g[i][j];

  for(i = 1; i
<= 2*n; ++i)

   for(j = 1; j
<= 2*n; ++j)

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

  int ans = -INF;

  for(i = 1; i <=
n; ++i)

   for(j = 1; j
<= n; ++j)

    for(k
= 1; k <= n; ++k)

     for(p
= 1; p <= n; ++p)

      ans
= max(ans,
sum[i+k-1][j+p-1]-sum[i+k-1][j-1]-sum[i-1][j+p-1]+sum[i-1][j-1]);

  printf("%d\n", ans);

 }

 return 0;

}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: