Spiral Maximum
Time Limit:3000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u
Description
Let's consider a k × k square, divided into unit squares. Please note that k ≥ 3 and is odd. We'll paint squares starting from the upper left square in the following order: first we move to the right, then down, then to the left, then up, then to the right again and so on. We finish moving in some direction in one of two cases: either we've reached the square's border or the square following after the next square is already painted. We finish painting at the moment when we cannot move in any direction and paint a square. The figure that consists of the painted squares is a spiral.
![](https://i-blog.csdnimg.cn/blog_migrate/6c7a9569f5d90a3376a7619317ea2b0d.png)
You have an n × m table, each of its cells contains a number. Let's consider all possible spirals, formed by the table cells. It means that we consider all spirals of any size that don't go beyond the borders of the table. Let's find the sum of the numbers of the cells that form the spiral. You have to find the maximum of those values among all spirals.
Input
The first line contains two integers n and m (3 ≤ n, m ≤ 500) — the sizes of the table.
Each of the next n lines contains m space-separated integers: the j-th number in the i-th line aij ( - 1000 ≤ aij ≤ 1000) is the number recorded in the j-th cell of the i-th row of the table.
Output
Print a single number — the maximum sum of numbers among all spirals.
Sample Input
6 5 0 0 0 0 0 1 1 1 1 1 0 0 0 0 1 1 1 1 0 1 1 0 0 0 1 1 1 1 1 1
17
3 3 1 1 1 1 0 0 1 1 1
6
6 6 -3 2 0 1 5 -1 4 -1 2 -3 0 1 -5 1 2 4 1 -2 0 -2 1 3 -1 2 3 1 4 -3 -2 0 -1 2 -1 3 1 2
13
Hint
In the first sample the spiral with maximum sum will cover all 1's of the table.
In the second sample the spiral may cover only six 1's.
题意:
在给出的n*n的矩阵中找到一个k*k的最大子矩阵(k>=3 && k为奇数)。子矩阵的值为从该矩阵左上角开始的蛇形(优先方向 右,下,左,上)上的数值之和。
思路:
题很好 和最大矩阵和相似,仔细分析下就可以发现这个求一个(r, c)开始的k*k子矩阵的值可以由对应的(r+2, c+2) 的 (k-4)*(k-4) 的子矩阵的值通过O(1)得到。所以可以直接递推
问题:
矩阵必须选择一个,也就是说ans初始值不能为0, 应该为-INF
#include <stdio.h>
#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"
#define oform1 "%I64d"
#else
typedef long long LL;
#define iform "%lld"
#define oform "%lld\n"
#define oform1 "%lld"
#endif
#define S64I(a) scanf(iform, &(a))
#define P64I(a) printf(oform, (a))
#define S64I1(a) scanf(iform1, &(a))
#define P64I1(a) printf(oform1, (a))
#define REP(i, n) for(int (i)=0; (i)<(n); (i)++)
#define REP1(i, n) for(int (i)=1; (i)<=(n); (i)++)
#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 = 500 + 20;
int n, m;
int A[maxn][maxn];
int rowSum[maxn][maxn], columSum[maxn][maxn];
int getQ(int r, int c, int k) {
if(k == 1) return A[r][c];
if(k == 2) return A[r][c] + A[r][c+1] + A[r+1][c+1];
int t = rowSum[r][c+k-1] - rowSum[r][c-1];
t += rowSum[r+k-1][c+k-1] - rowSum[r+k-1][c-1];
t += columSum[r+k-1][c+k-1] - columSum[r-1][c+k-1];
t += columSum[r+k-1][c] - columSum[r+1][c];
t = t - A[r][c+k-1] - A[r+k-1][c] - A[r+k-1][c+k-1];
return t;
}
bool isok(int r, int c, int k) {
return r > 0 && r+k-1 <= n && c > 0 && c+k-1 <= m;
}
int main() {
while(scanf("%d%d", &n, &m) != EOF) {
FOR(i, 0, n) rowSum[i][0] = 0, columSum[0][i] = 0;
REP1(i, n) REP1(j, m) {
scanf("%d", &A[i][j]);
rowSum[i][j] = A[i][j] + rowSum[i][j-1];
columSum[i][j] = A[i][j] + columSum[i-1][j];
}
int ans = -INF;
for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++) {
int r = i;
int c = j;
int k = 1;
int son = 0;
while(isok(r, c, k)) {
int sum = getQ(r, c, k) + son;
if(k >= 3 && k%2==1 && sum > ans) {
ans = sum;
}
son = sum + A[r][c-1];
r -= 2;
c -= 2;
k += 4;
} // 这里比较累赘
r = i;
c = j;
k = 3;
son = 0;
while(isok(r, c, k)) {
int sum = getQ(r, c, k) + son;
if(k >= 3 && k%2==1 && sum > ans) {
ans = sum;
}
son = sum + A[r][c-1];
r -= 2;
c -= 2;
k += 4;
}
}
}
printf("%d\n", ans);
}
return 0;
}