用暴力查找会超时。
思路:存在一些和之前计算过了就不用再计算了。
例如:
1
4 5 2 3
4 5 2 3
3 | 361 |
649 |
676 |
588 |
992 |
762 |
156 |
993 |
169 |
662 |
34 |
638 |
89 |
543 |
525 |
165 |
254 |
809 |
280 |
第1次计算(竖着)
3+992 |
361+762 |
649+156 |
676+933 |
588+169 |
设最大值m = 0;
第一次计算 sum = 3+992 +361+762 + 649+156
第二次计算 sum = 3+992 +361+762 +
649+156 + 676+933 - 3-922 (红色的为重复计算部分)
649+156 + 676+933 - 3-922 (红色的为重复计算部分)
第三次计算 sum = 361+762+649+156+676+933+588+169-361-762
第2次计算(竖着)
992+662 |
762+34 |
156+638 |
933+89 |
169+543 |
第一次计算 sum = 992+662+762+34+156+638
第二次计算 sum = 992+662+762+34+156+638+922+89-992-662
第三次计算 sum = 762+34+156+638+922+89+169+543-762-34
横着和竖着的地方都有重复计算的地方,计算过的地方就可以不用一直计算,用一个数组记录。
#include <iostream> using namespace std; #define MAX 1001 int g[MAX][MAX]; int s[MAX]; int num, line, row, x, y; int max(int n[])//计算每一行 { int i, nx, ny, m, sum; nx = 0; ny = x; m = 0; for (i=0; i<y; i++) m += n[i]; sum = m; while (ny!=row) { m = m - n[nx] + n[ny]; nx++; ny++; if (sum < m) sum = m; } return sum; } int main() { int i, j, m, sum, nx, ny, t; cin>>num; while (num--) { cin>>line>>row>>x>>y; for (i=0; i<line; i++)//记录每一列 for (j=0; j<row; j++) scanf("%d", &g[i][j]); m = 0; for (j=0; j<row; j++) { sum = 0; for (i=0; i<y; i++) sum += g[i][j]; s[j] = sum; } m = max(s); nx = 0; ny = x; for (i=0; i<line-x; i++) { for (j=0; j<row; j++) s[j] = s[j] - g[nx][j] + g[ny][j]; t = max(s); if (t > m) m = t; nx++; ny++; } cout<<m<<endl; } return 0; }