思路: 先将所有价值w的前缀和表示出来,然后枚举所有小正方形,根据右下角坐标来找出最大值
# include<iostream>
# include<cstdio>
# include<cstring>
# include<algorithm>
using namespace std;
const int N = 5010;
int n,m;
int s[N][N];
int main()
{
int cnt,r;
cin >> cnt >> r;
r = min(5001,r);//排除r大于边界
m = n = r;
while(cnt--)
{
int x,y,w;
cin >> x >> y >> w;
x++;
y++;
n = max(n,x);//更新长度,防止x和y大于边长
m = max(m,y);
s[x][y] += w;//题目说不同目标可能在同一位置
}
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= m;j++)
{
s[i][j] += s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1];//算出前缀和矩阵
}
}
int res = 0;
//枚举所有边长为r的正方形
for(int i = r;i <= n;i++)
{
for(int j = r;j <= m;j++)
{
res = max(res,s[i][j] - s[i - r][j] - s[i][j - r] + s[i - r][j - r]);//找出边长为人的正方形最大的前缀和
}
}
cout << res << endl;
return 0;
}