由于xi yi在0到5000之间,我们之前学的前缀和模板都是从下标1开始,我们就把x和y各自加1就好了,也就是在1到5001之间了,题目又说了,同一位置可能有多个目标,所以我们在一个位置求价值的时候应该用加等来求和
我们回顾一下之前构建前缀和数组的公式
公式应该是f[i][j]=f[i-1][j]+f[i][j-1]-f[i-1][j-1]+a[i][j]
之后我们要求炸毁的最大价值,就要枚举出所有变成为m的正方形,于是乎我们就可以从m,m这个坐标开始依次往后枚举,每次枚举的坐标是x2,y2 那么左上角的坐标就应该是 x2-m+1,y2-m+1
再结合我们之前学的求两点之间的矩形面积的公式
D=U-(A+B)-(A+C)+A 也就是D = f[x2][y2]-f[x1-1][y2]-f[x2][y1-1]+f[x1-1][y1-1]
好了,我们直接来写代码吧
#include <iostream>
using namespace std;
const int N = 5010;
int n, m;
typedef long long LL;
int a[N][N];
int f[N][N];int main()
{cin >> n >> m;for (int i = 1; i <= n; i++){int x, y, v; cin >> x >> y >> v;x++, y++;a[x][y] += v;}n = 5001;for (int i = 1; i <= n; i++){for (int j = 1; j <= n; j++){f[i][j] = f[i - 1][j] + f[i][j - 1] - f[i - 1][j - 1] + a[i][j];}}int ret = 0;for (int x2 = m; x2 <= n; x2++){for (int y2 = m; y2 <= n; y2++){int x1 = x2 - m + 1, y1 = y2 - m + 1;ret = max(ret, f[x2][y2] - f[x1 - 1][y2] - f[x2][y1 - 1] + f[x1 - 1][y1 - 1]);}}cout << ret << endl;return 0;
}