洛谷P2280 激光炸弹
题目描述
一种新型的激光炸弹,可以摧毁一个边长为m的正方形内的所有目标。现在地图上有n个目标,用整数xi,yi表示目标在地图上的位置,每个目标都有一个价值vi.激光炸弹的投放是通过卫星定位的,但其有一个缺点,就是其爆破范围,即那个边长为m的边必须与x轴,y轴平行。若目标位于爆破正方形的边上,该目标不会被摧毁。
现在你的任务是计算一颗炸弹最多能炸掉地图上总价值为多少的目标。
输入格式
输入的第一行为整数n和整数m,
接下来的n行,每行有3个整数x,y,v,表示一个目标的坐标与价值。
输出格式
输出仅有一个正整数,表示一颗炸弹最多能炸掉地图上总价值为多少的目标(结果不会超过32767)。
输入输出样例
输入 #1
2 1
0 0 1
1 1 1
输出 #1
1
说明/提示
数据规模与约定
- 对于 100% 的数据,保证1≤n≤104,0≤xi,yi≤5×103,1≤m≤5×103,1≤vi<100。
思路:先计算二维前缀和,然后通过二维前缀和去计算炸弹能炸毁的价值
代码:
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m;
cin>>n>>m;
m=min(m,5001);
int x[n],y[n],v[n]={},maxx=m,maxy=m;
for(int i=0;i<n;i++){
cin>>x[i]>>y[i]>>v[i];
maxx=max(maxx,x[i]);
maxy=max(maxy,y[i]);
}
int s[maxx+1][maxy+1]={};
for(int i=0;i<n;i++){
s[x[i]][y[i]]=v[i];
}
for(int i=0;i<=maxx;i++){
for(int j=0;j<=maxy;j++){
if(i==0&&j==0){
s[i][j]=s[i][j];
}
else if(i==0&&j!=0){
s[i][j]=s[i][j-1]+s[i][j];
}
else if(i!=0&&j==0){
s[i][j]=s[i-1][j]+s[i][j];
}
else{
s[i][j]=s[i-1][j]+s[i][j-1]+s[i][j]-s[i-1][j-1];
}
}
}
int max0=0;
for(int i=(m-1);i<=maxx;i++){
for(int j=(m-1);j<=maxy;j++){
int i1=i-(m-1),j1=j-(m-1);
int s1;
if(i1==0&&j1==0){
s1=s[i][j];
}
else if(i1==0&&j1!=0){
s1=s[i][j]-s[i][j1-1];
}
else if(i1!=0&&j1==0){
s1=s[i][j]-s[i1-1][j];
}
else{
s1=-s[i][j1-1]-s[i1-1][j]+s[i1-1][j1-1]+s[i][j];
}
max0=max(max0,s1);
}
}
cout<<max0;
return 0;
}