算法竞赛进阶指南 激光炸弹
原题目链接
问题描述
地图上有 N
个目标点,用整数 Xᵢ, Yᵢ
表示目标在地图上的位置,每个目标都有一个价值 Wᵢ
。
注意:不同目标可能在同一位置。
现在有一种新型的激光炸弹,可以摧毁一个包含 R × R
个位置的正方形区域内的所有目标。
激光炸弹的投放是通过卫星定位的,但有一个缺点:其爆炸范围,也就是正方形的边必须与 x、y 轴平行。位于正方形边上的点不会爆炸。
请计算:一颗炸弹最多能炸掉地图上目标的总价值为多少?
输入格式
- 第一行输入两个正整数
N
和R
,分别表示地图上的目标数量和正方形的边长,数据用空格隔开。 - 接下来的
N
行,每行包含三个整数Xᵢ Yᵢ Wᵢ
,分别表示目标的横坐标、纵坐标和该目标的价值。
输出格式
输出一个正整数,表示一颗炸弹最多能炸掉的目标总价值。
数据范围
0 < N ≤ 10000
0 ≤ R ≤ 10^9
0 ≤ Xᵢ, Yᵢ ≤ 5000
0 ≤ Wᵢ ≤ 1000
输入样例
2 1
0 0 1
1 1 1
输出样例
1
c++代码
#include<bits/stdc++.h>
#include<stdio.h>
using namespace std;
int R, N, X, Y, W, m = 0, n = 0, ans = 0;
int g[5500][5500];
int main() {
scanf("%d %d", &N, &R);
R = min(R, 5001);
m = R, n = R;
R--;
while(N--) {
scanf("%d %d %d", &X, &Y, &W);
g[X + 1][Y + 1] += W;
m = max(m, X + 1);
n = max(n, Y + 1);
}
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
g[i][j] += g[i - 1][j] + g[i][j - 1] - g[i - 1][j - 1];
}
}
for (int i = R + 1; i <= m; i++) {
for (int j = R + 1; j <= n; j++) {
ans = max(ans, g[i][j] - g[i - R - 1][j] - g[i][j - R - 1] + g[i - R - 1][j - R - 1]);
}
}
cout << ans;
return 0;
}//by wqs
考察二维前缀和