激光导弹(二维前缀和)

题目:
地图上有 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
输入:
2 1
0 0 1
1 1 1
输出:
1

这题就是一个裸的二维前缀和,但是有些地方要细节;
借鉴了yxc的代码,因为我被正方形内坑了,和r的大小RE了

题目注意事项:是正方形内 所以求的实际是r-1大小的正方形能摧毁的最大总值, 还有就是因为 x,y,是在5000以内,所以对r进行一个范围限制。
c++代码如下:

扫描二维码关注公众号,回复: 9521953 查看本文章
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#pragma G++ optimize(2)
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const double eps = 1e-5;
const int mod = 999911659;
const int N = 5010;
typedef pair<int,int> pii;
int sum[N][N];
int main(){
	IOS;
	int q,r;cin>>q>>r;
	r=min(5001,r);//限制r大小
	int x,y,w,n=5001,m=5001;
	while(q--)
	{
		cin>>x>>y>>w;
		++x,++y;//从1开始
		sum[x][y]+=w;//加等于防止重复加点
	}
	//前缀和预处理
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			sum[i][j]+=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
	//扫一遍r-1大小的正方形
	int res=0;
	for(int i=r;i<=n;i++)
		for(int j=r;j<=m;j++)
			res=max(res,sum[i][j]-sum[i-r][j]-sum[i][j-r]+sum[i-r][j-r]);
	cout<<res<<endl;
	return 0;
}

如有问题,还请联系。

发布了8 篇原创文章 · 获赞 9 · 访问量 271

猜你喜欢

转载自blog.csdn.net/qq_45604735/article/details/104603472