激光炸弹--算法竞赛进阶指南

题目描述
地图上有 N 个目标,用整数Xi,Yi表示目标在地图上的位置,每个目标都有一个价值Wi。

注意:不同目标可能在同一位置。

现在有一种新型的激光炸弹,可以摧毁一个包含 R×R 个位置的正方形内的所有目标。

激光炸弹的投放是通过卫星定位的,但其有一个缺点,就是其爆炸范围,即那个正方形的边必须和x,y轴平行。

求一颗炸弹最多能炸掉地图上总价值为多少的目标。

输入格式
第一行输入正整数 N 和 R ,分别代表地图上的目标数目和正方形的边长,数据用空格隔开。

接下来N行,每行输入一组数据,每组数据包括三个整数Xi,Yi,Wi,分别代表目标的x坐标,y坐标和价值,数据用空格隔开。

输出格式
输出一个正整数,代表一颗炸弹最多能炸掉地图上目标的总价值数目。

数据范围
0≤R≤10^9
0<N≤10000
0≤Xi,Yi≤5000
0≤Wi≤1000

输入样例
2 1
0 0 1
1 1 1

输出样例
1

AC代码

/*
其实这也是一个前缀和的问题
其实这就是一个计算一个区域R的里面和最大的值
只需要遍历所有的R即可,这样的时间复杂度极限下,
遍历所有也不过是5000*5000,也就是两千五百万 
*/


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

using namespace std;

int N, R;
int map[5005][5005];




int main()
{
	memset(map, 0, sizeof(int)*5005*5005);
	
	cin >> N >> R;
	R = min(5001,R);
	int x, y, w;
	int maxX = 0, maxY = 0;
	//千万记住!!! 如果摧毁的范围是R*R,那么此时最大X,Y坐标一定大于等于R 
	//你没有这部,那么在后面步奏,会因为R过大,导致出现错误 
	maxX = R, maxY = R;
	for(int i = 0; i < N; i++)
	{
		scanf("%d %d %d",&x,&y,&w);
		++x,++y;
		//向右下角移一个,方便后面计算前缀和 
		maxX = max(x, maxX);
		maxY = max(y, maxY);
		map[x][y] += w;//千万记住,如果在同一个地方~他们会相加的!!! 
	}
	
	
	for(int i = 1; i <= maxX ; ++i)
	{
		for(int j = 1; j <= maxY && j >= 0; ++j)
		{
			map[i][j] = map[i-1][j] + map[i][j-1] - map[i-1][j-1] + map[i][j];
		}
	}
	
	int count = 0;
	
	for(int i = R; i <= maxX; ++i)
	{
		for(int j = R; j <= maxY; ++j)
		{
			count = max(count, map[i][j]-map[i-R][j]-map[i][j-R]+map[i-R][j-R]);
		} 
	}
	
	cout << count << endl;
	
	return 0;
} 
发布了40 篇原创文章 · 获赞 50 · 访问量 4697

猜你喜欢

转载自blog.csdn.net/qq_43800455/article/details/105334934