《算法竞赛进阶指南》[HNOI2003]激光炸弹--题解

A-[HNOI2003]激光炸弹_0x03 基本算法-递归

https://ac.nowcoder.com/acm/contest/999/A

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

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

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


前缀和
其实可以把它理解为数学上的数列的前n项和(对于一个一维数组的前缀和)。
我们定义对于一个数组a的前缀和数组s,s[i] = a[1]+a[2]+...+a[i].

二维前缀和
与一维前缀和类似,设s[i][j]表示所有a[i'][j']的和。(1≤i'≤i,1≤j'≤j)
有一点像“矩形的面积”那样,把一整块区域的值都加起来。

当给出一个数列s,要求你回答m次询问,每次询问下标j到k(k > j)的和。怎么算更快呢?暴力发就是每次询问都执行一次相加操作,然后输出结果。
可是这样算会TLE的。可以先提前算好每一次的前缀和,再用s[k]-s[j],这样便会使计算量大大减小。

图片说明
(图片来源于网络)

假设在这个矩阵(二维数组)中,我们要求和的是上图中红区。现在我们已经预处理出了所有点的前缀和,现在给定两个点(x1,y1),(x2,y2),我们要求 以这两个点连线为对角线的一个子矩阵的数值之和。

首先我们可以把s[x2][y2]求出来,它代表整个大矩形的前缀和,然后我们分别减去它左边多出来的一块的前缀和和下边多出来一块的前缀和。
最后可以发现绿色部分多剪了一次,加回来,就ok了。
所以对于一次的查询答案ans应该等于

废话少说直接上代码:

完整C++版AC代码

#include <iostream>
#include <algorithm>
#include <cstdio>

using namespace std;

const int N = 5010;//这个N表示点最多的数量
int g[N][N];

int main() {

    int N, R;//为了方便就重名了,两个N重名是没关系的,因为会优先选择函数里的
    cin >> N >> R;
    int xx = R, yy = R;//xx和yy表示边界,初始化为最小的R

    for (int i = 0,x,y,w; i < N; ++i) {
        cin >> x >> y >> w;
        x++; y++;//坐标x,y都要加1,因为这道题目的坐标是从0开始的
        g[x][y] = w;
        xx = max(xx, x);
        yy = max(yy, y);
    }

    for (int i = 1; i <= xx; i++) 
        for (int j = 1; j <= yy; j++)
            g[i][j] = g[i - 1][j] + g[i][j - 1] - g[i - 1][j - 1] + g[i][j];//求前缀和

    int ans = 0;
    for (int i = R; i <= xx; i++) {
        for (int j = R; j <= yy; j++) {
            ans = max(ans, g[i][j] - g[i - R][j] - g[i][j - R] + g[i - R][j - R]);//用提前算好的前缀和减去其他部分再补上多剪的那部分
        }
    }
    printf("%d\n", ans);
    return 0;
}
全部评论
他把坐标轴原点从(0,0)变成(1,1),但算边界的时候是从R开始,而不是R+1,这点保证了正方形边缘不算
2 回复 分享
发布于 2020-07-02 10:19
想请问下正方形边缘不算是怎么体现的?
2 回复 分享
发布于 2020-01-29 13:59
这个边缘不能算也有太有点歧义了,直接就说正方形括起来的都算不就行了嘛
点赞 回复 分享
发布于 2023-11-07 11:50 湖南
博主,为什么这里的x1和y1 都需要-1啊 s[x2][y2]−s[x2][y1−1]−s[x1−1][y2]+s[x1−1][y1−1] 。
点赞 回复 分享
发布于 2020-07-03 10:01

相关推荐

白火同学:1、简历可以浓缩成一页,简历简历先要“简”方便HR快速过滤出有效信息,再要“历”用有效信息突出个人的含金量。 2、教育背景少了入学时间~毕业时间,HR判断不出你是否为应届生。 3、如果你的平台账号效果还不错,可以把账号超链接或者用户名贴到对应位置,一是方便HR知道你是具体做了什么内容的运营,看到账号一目了然,二是口说无凭,账号为证,这更有说服力。
面试被问期望薪资时该如何...
点赞 评论 收藏
分享
已经入职字节快一个月了,突然想起来之前那段时间的面经没有发,先发一下timeline吧。Tiktok&nbsp;内容安全平台(人才库电话捞我):电话10.28&nbsp;-&gt;&nbsp;一面10.30(我觉得你跟我们组业务挺match的,然后过了三天问hr挂了,应该是别人流程更快)阿里淘天:投递11.11-&gt;约面11.12-&gt;一面11.14(问得很简单,30分钟,手撕八股全过无后续)Kpi面腾讯wxg&nbsp;微信小程序:投递11.13&nbsp;-&gt;约面11.14-&gt;&nbsp;一面11.17&nbsp;(究极无敌拷打,问我多模态大模型涉及的算法?但是人很好)-&gt;11.19流程终止小红书&nbsp;风控平台:投递11.16&nbsp;—约面11.17&nbsp;&nbsp;-&gt;一面11.18&nbsp;(抽象的面试官,面试感觉一般,问得前端网页安全相关的,确实没准备)-&gt;11.20挂百度&nbsp;百家号:投递11.14&nbsp;—&gt;约面11.14&nbsp;-&gt;一面11.14(当场约2面)-&gt;二面11.24-&gt;口头告知offer,&nbsp;拒绝(原因是业务不太好)美团&nbsp;技术平台投递11.17&nbsp;-&gt;&nbsp;约面(忘记了,没多久)&nbsp;-&gt;一面11.19&nbsp;-&gt;二面11.21&nbsp;(字节offer不想面了)快手&nbsp;电商业务投递11.17&nbsp;-&gt;&nbsp;约面11.18&nbsp;-&gt;一面11.19&nbsp;-&gt;&nbsp;二面11.21(拒了)腾讯wxg&nbsp;微信支付(被捞):(直接发面试邮件)技术一面12.05&nbsp;-&gt;技术二面12.11&nbsp;-&gt;技术三面12.17&nbsp;-&gt;&nbsp;hr面已拒绝(了解业务后拒绝,但是有转正hc,感觉还蛮可惜)字节跳动&nbsp;xxxx:东家就不放具体的时间线了,大概是面完第二天就能知道结果,除了有几天ld请假了没填面评。不去wxg还有个原因是还在期末周,深圳学校来回太麻烦了,至少现在在的组感觉能学到很多的东西,自己的选择应该也没错。还是感概一下,一年前大二的时候投简历海投基本上石沉大海,无论大小厂约面比例很少。现在基本上投了就有面试,还都是以前梦寐以求的大厂,现在自己也有了更多的选择,也没有投太多简历。也感谢上一段实习的经历,很有意思的项目,无论是字节,腾讯,还是美团基本都有聊这个项目。面经需要等一下,也许等周末有空了再发给各位uu,感兴趣可以关注一下~有想要交流学习的同学也可以私信我,目前人在北京大钟寺~,可以找搭子~
正能量的牛可乐:这么多大厂面试下来,不仅摸清了不同公司的面试风格,还能精准避雷业务不匹配的岗位,血赚
实习简历求拷打
点赞 评论 收藏
分享
评论
35
3
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务