激光炸彈--算法競賽進階指南

題目描述
地圖上有 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;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章