有那么一丢丢拖延症,之前说要一天一道题结果昨天忘记了,所以啊今天做两道,哼。下面这道关于二维数组前缀和的题呢交的时候老是给我报什么段错误和数组越界,检查了好久发现遍历求区域最大值忘记减去边长R了,下次必须得注意这个问题。
登录—专业IT笔试面试备考平台_牛客网 这个是这道题的链接。
题目描述
一种新型的激光炸弹,可以摧毁一个边长为R的正方形内的所有的目标。
现在地图上有n(N ≤ 10000)个目标,用整数Xi,Yi(其值在[0,5000])表示目标在地图上的位置,每个目标都有一个价值。
激光炸弹的投放是通过卫星定位的,但其有一个缺点,就是其爆破范围,即那个边长为R的正方形的边必须和x,y轴平行。
若目标位于爆破正方形的边上,该目标将不会被摧毁。
输入描述:
输入文件的第一行为正整数n和正整数R,接下来的n行每行有3个正整数,分别表示 xi,yi ,vi 。
输出描述:
输出文件仅有一个正整数,表示一颗炸弹最多能炸掉地图上总价值为多少的目标(结果不会超过32767)。
示例1
输入
2 1 0 0 1 1 1 1
输出
1
废话不多说,还是上我的图片吧。
总之就是上面笔记中描述的意思。接下来上代码(里面有一个二维前缀和的知识可以看这个「土」秘法地震_牛客博客)。
#include <iostream>
#include <algorithm>
int sum[5005][5005] = {0};//初始化为0;
int n, R;
int main(){
scanf("%d %d",&n, &R);
for( int i = 0; i < n; i++ ){
int x, y, v;
scanf("%d %d %d",&x,&y,&v);
sum[x+1][y+1] = v;//从第一行开始赋值。
}
for( int i = 1; i <= 5001; i++ )
for( int j = 1; j <= 5001; j++ ){
sum[i][j] = sum[i][j-1] + sum[i-1][j] - sum[i-1][j-1]+sum[i][j];
}
int ma = 0;
for( int i = 0; i <= 5000-R; i++ )//注意这里要减去R,因为下面sum[i+R],要是等于5000的话会有数组越界,发生段错误。
for( int j = 0; j <= 5000-R; j++ ){
ma = std::max(sum[i+R][j+R]+sum[i][j]-sum[i+R][j]-sum[i][j+R],ma);
}
printf("%d\n",ma);
return 0;
}