題目描述
地圖上有 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;
}