Acwing99. Laser bomb (application of two-dimensional prefix sum)

There are N targets on the map, and integers Xi, Yi represent the position of the target on the map, and each target has a value Wi.

NOTE : Different targets may be in the same location.

There is now a new type of laser bomb that destroys all targets within a square containing R×R positions.

The launch of the laser bomb is positioned by satellite, but it has a disadvantage, that is, its explosion range, that is, the sides of the square must be parallel to the x and y axes.

Find out how much a bomb can blow up the total value of targets on the map.

input format

The first line inputs positive integers N and R, which respectively represent the number of targets on the map and the number of horizontal and vertical positions contained in the square, and the data are separated by spaces.

In the next N lines, enter a set of data in each line, each set of data includes three integers Xi, Yi, Wi, which represent the x coordinate, y coordinate and value of the target, and the data are separated by spaces.

output format

Output a positive integer, representing the total value of a bomb that can blow up the targets on the map at most.

data range

0≤R≤109
0<N≤10000,
0≤Xi,Yi≤5000
0≤Wi≤1000

Input sample:

2 1
0 0 1
1 1 1

Sample output:

1

 

 

The AC code is as follows

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

#define N 5002
int f[N][N];

int main() {

    int n, r;
    int max_x, max_y;
    int x = 0, y = 0, w = 0;
    cin >> n >> r;
    r = min(r, 5001); // 爆炸范围超过5001时覆盖了所有目标范围,因此没必要考虑超出范围。
    max_x = max_y = r;// 最小的爆炸计算范围是在一个最小爆炸范围之内计算
    for (int i = 0; i < n; ++i) {
        cin >> x >> y >> w;
        f[++x][++y] += w; // 将目标范围统一偏移1,便于边界计算。
        max_x = max(x, max_x); // 如果有目标落在一个最小爆炸范围之外,则扩大计算范围。
        max_y = max(y, max_y);
    }
    // 下面两个循环的计算公式都需要自己用手画一下,才能获得利用二维前缀和计算总价值的结果
    for (int i = 1; i <= max_x; ++i) { // 循环从偏移的1开始
        for (int j = 1; j <= max_y; ++j) {
            f[i][j] = f[i - 1][j] + f[i][j - 1] - f[i - 1][j - 1] + f[i][j];
        }
    }

    int ans = 0;
    for (int i = r; i <= max_x; ++i) {
        for (int j = r; j <= max_y; ++j) {
            ans = max(ans, f[i][j] - f[i - r][j] - f[i][j - r] + f[i - r][j - r]);
        }
    }

    cout << ans << endl;

    return 0;
} 

Guess you like

Origin blog.csdn.net/weixin_52030368/article/details/129090011