分析:直接一个一个地去暴力枚举分数比较少,我们需要一种比较快的统计一定空间内1的数量,标准做法是前缀和,但是二维前缀和维护的是一个矩形内的值,这个是旋转过的该怎么办?可以把图旋转45°,不过这样比较考验码力,我们可以考虑维护每一行的前缀和,写得好常数小一点加上读入优化就能A了.
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; long long ans = 0,n, m, sum[2010][2010]; long long read() { long long res = 0, f = 1; char ch = getchar(); while (ch < '0' || ch > '9') if (ch == '-') { f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { res = res * 10 + ch - '0'; ch = getchar(); } return res * f; } int main() { n = read(); m = read(); for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) { sum[i][j] = read(); sum[i][j] += sum[i][j - 1]; } for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) { long long maxx = sum[i][min(n, j + m - 1)] - sum[i][max((long long)0, j - m)]; for (int k = 1; k < m; k++) { int l = max(j - m + k,(long long)0), r = min(j + m - 1 - k,n); if (i + k <= n) maxx += sum[i + k][r] - sum[i + k][l]; if (i - k >= 1) maxx += sum[i - k][r] - sum[i - k][l]; } ans = max(maxx, ans); } printf("%lld ", ans); return 0; }