Maximum sum on a torus
Input: Standard InputOutput: Standard Output
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.
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 |
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 Output for 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 | 15 45 |
Problem setter: Jimmy Mårdell
Special Thanks: Derek Kisman, Md. Kamruzzaman
题意:给一个n*n的矩阵,矩阵左右连接,上下连接。求所给矩阵的最大(元素和)子矩阵。
思路:把矩阵copy份拼在原矩阵的右,下,右下,得到一个2n*2n的矩阵,然后问题就变成了在这个2n*2n的矩阵中找出一个最大为n*n的最大子矩阵。
#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <map>
#include <cmath>
#include <queue>
#include <set>
using namespace std;
//#define WIN
#ifdef WIN
typedef __int64 LL;
#define iform "%I64d"
#define oform "%I64d\n"
#else
typedef long long LL;
#define iform "%lld"
#define oform "%lld\n"
#endif
#define S64I(a) scanf(iform, &(a))
#define P64I(a) printf(oform, (a))
#define FOR(i, s, t) for(int (i)=(s); (i)<(t); (i)++)
const int INF = 0x3f3f3f3f;
const double eps = 10e-9;
const double PI = (4.0*atan(1.0));
const int maxn = 200;
int A[maxn][maxn];
int sum[maxn][maxn];
int main() {
int T;
scanf("%d", &T);
while(T--) {
int n;
scanf("%d", &n);
for(int i=1; i<=n; i++) {
for(int j=1; j<=n; j++) {
scanf("%d", &A[i][j]);
A[i+n][j] = A[i][j+n] = A[i+n][j+n] = A[i][j];
}
}
memset(sum, 0, sizeof(sum));
for(int i=1; i<=2*n; i++) {
for(int j=1; j<=2*n; j++) {
sum[i][j] = A[i][j] + sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1];
}
}
int ans = 0;
for(int i=1; i<=2*n; i++) {
for(int j=1; j<=2*n; j++) {
for(int ki=1; ki<=n; ki++) if(i >= ki) {
for(int kj=1; kj<=n; kj++) if(j >= kj) {
int t = sum[i][j];
t = t - sum[i-ki][j] - sum[i][j-kj] + sum[i-ki][j-kj];
if(t > ans) {
ans = t;
// printf("%d %d %d %d\n", i-ki+1, j-kj+1, i, j);
}
}
}
}
}
printf("%d\n", ans);
}
return 0;
}