AcWing-99.激光炸弹
¶首先来首歌曲来放松一下吧!
题目链接:99. 激光炸弹
¶题目背景:
¶题目描述
地图上有 N 个目标,用整数Xi,Yi表示目标在地图上的位置,每个目标都有一个价值Wi。
注意:不同目标可能在同一位置。
现在有一种新型的激光炸弹,可以摧毁一个包含 R×R 个位置的正方形内的所有的目标。
激光炸弹的投放是通过卫星定位的,但其有一个缺点,就是其爆炸范围,即那个正方形的边必须和x,y轴平行。
若目标位于爆破正方形的边上,该目标不会被摧毁!
求一颗炸弹最多能炸掉地图上总价值为多少的目标。
¶输入格式
第一行输入正整数 N 和 R ,分别代表地图上的目标数目和正方形的边长,数据用空格隔开。
接下来N行,每行输入一组数据,每组数据包括三个整数Xi,Yi,Wi,分别代表目标的x坐标,y坐标和价值,数据用空格隔开。
¶输出格式
输出一个正整数,代表一颗炸弹最多能炸掉地图上目标的总价值数目。
¶数据范围
0≤ R ≤109
0< N ≤10000
0≤ Xi,Yi ≤5000
0≤ Wi ≤1000
¶输入样例:
1 |
|
¶输出样例:
1 |
|
¶题目分析:
¶题目要求:
就是在一个地图上放一个边长为 r 正方形,最后要输出这个正方形扣住的区域权值最大的值!
注意:正方形的边上的不算!
¶解题思路:
首先引入一维前缀和:
作用:可以在O(1)的时间内求出某一段区间的和!
举个例子:
a[1]、a[2] … a[n]
引入s[i]前缀和:
s[i] = s[0]…+s[i]
加入求a[7] ~ a[40] 那么就等于s[40] - s[6]!
接着引入二维前缀和:
就是变成了一个坐标:
首先给出递归式:s[i][j] += s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1];
画个图:紫色的自己加上红色和绿色构成的矩形,再加上另一个红色和绿色构成的矩形,在减去多加的绿色部分!
接下来开始预处理前缀和,在输入是让x和y都加了1,这样在预处理时,不会出现负数下标,免得处理边界问题!
由于每个点不止一个目标:所以数组要进行累加:g[x][y] += w;
接下来开始划分边长为R的矩形,要保证边长足够,所以i和j 最小也得从R开始,此时的(i, j) 指向的是矩形的右下角,这样可以保证不越界!
递推式:g[i][j] - g[i - r][j] - g[i][j - r] + g[i - r][j - r]
很好理解的:此时的(i , j)表示的行和列,即第i行第j列!
如下图:
假如:r = 2,要计算 g[3][3]
为右下角时,需要减去画那两道红线所构成的两个矩形,再加上多减掉的交叉部分,这样剩下的就是从青绿色右下角开始的四个蓝色的圈,这样看来,得到的结果就不是R 边长了,而是R- 1的边长,这样也就可以保证边上的不被计算!
为什么不把右边和下边两条边也删掉了?
我看了好久!才发现:
不能删,删掉上和左就够了!
你可以在脑袋里想一下,将那个矩形在图上飘起来,会发现盖住的部分最多就是那四个蓝色的圈!而R - 1 就可以实现边上的不记录效果!
好好理解一下,可能有点绕!
¶题解:
1 |
|