NC20032 [HNOI2003]激光炸弹

题目

题目描述

一种新型的激光炸弹,可以摧毁一个边长为R的正方形内的所有的目标。

现在地图上有 \(n\) (\(N ≤ 10000\))个目标,用整数 \(Xi,Yi\) (其值在 \([0,5000]\) )表示目标在地图上的位置,每个目标都有一个价值。

激光炸弹的投放是通过卫星定位的,但其有一个缺点,就是其爆破范围,即那个边长为 \(R\) 的正方形的边必须和 \(x,y\) 轴平行。

若目标位于爆破正方形的边上,该目标将不会被摧毁。

输入描述

输入文件的第一行为正整数 \(n\) 和正整数 \(R\) ,接下来的 \(n\) 行每行有 \(3\) 个正整数,分别表示 \(x_i,y_i,v_i\)

输出描述

输出文件仅有一个正整数,表示一颗炸弹最多能炸掉地图上总价值为多少的目标(结果不会超过 \(32767\))。

示例1

输入

2 1
0 0 1
1 1 1

输出

1

备注

对于 \(100\%\) 的数据,保证 \(1≤n≤10^4\)\(0≤x_i,y_i≤5×10^3\)\(1≤m≤5×10^3\)\(1≤v_i<100\)

题解

知识点:前缀和,枚举。

考虑用二维前缀和维护一个方阵内目标价值总和。需要注意的是题目中指出方阵边界目标不被击毁,可以考虑将一个目标对应方阵的一个线段而不是一个点,能保证最大化击毁。

时间复杂度 \(O(1)\)

空间复杂度 \(O(1)\)

代码

#include <bits/stdc++.h>

using namespace std;


int a[5007][5007];
int main(){
    std::ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int n,m;
    cin>>n>>m;
    for(int i = 0;i<n;i++){
        int x,y;
        cin>>x>>y;
        cin>>a[x+1][y+1];
    }
    for(int i = 1;i<=5000;i++){
        for(int j = 1;j<=5000;j++){
            a[i][j] += a[i][j-1] + a[i-1][j] - a[i-1][j-1];
        }
    }
    int ans = 0;
    for(int i = 1;i<=5000;i++){
        for(int j = 1;j<=5000;j++){
            if(i+m-1<=5000 && j+m-1<=5000) ans = max(ans,a[i+m-1][j+m-1] - a[i+m-1][j-1] - a[i-1][j+m-1] + a[i-1][j-1]);
        }
    }
    cout<<ans<<'\n';
    return 0;
}
posted @ 2022-05-09 13:25  空白菌  阅读(125)  评论(0编辑  收藏  举报