P2280 [HNOI2003]激光炸弹(二维前缀和)

题目描述

一种新型的激光炸弹,可以摧毁一个边长为R的正方形内的所有的目标。现在地图上有n(n≤10000)个目标,用整数xi,yi(0≤xi,yi≤5000)表示目标在地图上的位置,每个目标都有一个价值0<vi<100。激光炸弹的投放是通过卫星定位的,但其有一个缺点,就是其爆破范围,即那个边长为R的正方形的边必须和x,y轴平行。若目标位于爆破正方形的边上,该目标将不会被摧毁。

现在你的任务是计算一颗炸弹最多能炸掉地图上总价值为多少的目标。

 

输入输出格式

输入格式:

输入文件的第一行为正整数n和正整数R,接下来的n行每行有3个正整数,分别表示 xi,yi ,vi 。

 

输出格式:

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

 

输入输出样例

输入样例#1: 复制
2 1
0 0 1
1 1 1


思路:这个题就是个二维数组,我们需要事先处理出二维前缀和,而后n²遍历每个炸弹区域(i,j)+(i-r,j-r)-(i-r,j)-(i,j-r)
至于题目所说边界的点不会摧毁,我们不妨认为这个点就在格子的中心,那么选区一个格子就刚好可以选择到这个点,类似于转换坐标系

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int maxn = 5555;
 5 int tree[maxn][maxn];
 6 int n,R;
 7 
 8 
 9 int main()
10 {
11     scanf("%d%d",&n,&R);
12     int maxx = 0;
13     for(int i=1;i<=n;i++)
14     {
15         int x,y,v;
16         scanf("%d%d%d",&x,&y,&v);
17         tree[x+1][y+1] = v;
18     }
19     for(int i=1;i<maxn;i++)
20     {
21         for(int j=1;j<maxn;j++)
22         {
23             tree[i][j] += tree[i-1][j] + tree[i][j-1] - tree[i-1][j-1];
24         }
25     }
26     for(int i=R;i<maxn;i++)
27     {
28         for(int j=R;j<maxn;j++)
29         {
30             maxx = max(maxx,tree[i][j]+tree[i-R][j-R]-tree[i-R][j]-tree[i][j-R]);
31         }
32     }
33     printf("%d\n",maxx);
34 }
View Code

 



posted @ 2018-12-17 14:30  进击的黑仔  阅读(279)  评论(0编辑  收藏  举报