99. 激光炸弹
地图上有 <span id="MathJax-Span-2" class="mrow"><span id="MathJax-Span-3" class="mi">NN 个目标,用整数 <span id="MathJax-Span-5" class="mrow"><span id="MathJax-Span-6" class="msubsup"><span id="MathJax-Span-7" class="mi">X<span id="MathJax-Span-8" class="texatom"><span id="MathJax-Span-9" class="mrow"><span id="MathJax-Span-10" class="mi">i<span id="MathJax-Span-11" class="mo">,<span id="MathJax-Span-12" class="msubsup"><span id="MathJax-Span-13" class="mi">Y<span id="MathJax-Span-14" class="texatom"><span id="MathJax-Span-15" class="mrow"><span id="MathJax-Span-16" class="mi">iXi,Yi 表示目标在地图上的位置,每个目标都有一个价值 <span id="MathJax-Span-18" class="mrow"><span id="MathJax-Span-19" class="msubsup"><span id="MathJax-Span-20" class="mi">W<span id="MathJax-Span-21" class="mi">iWi。
注意:不同目标可能在同一位置。
现在有一种新型的激光炸弹,可以摧毁一个包含 <span id="MathJax-Span-23" class="mrow"><span id="MathJax-Span-24" class="mi">R<span id="MathJax-Span-25" class="mo">×<span id="MathJax-Span-26" class="mi">RR×R 个位置的正方形内的所有目标。
激光炸弹的投放是通过卫星定位的,但其有一个缺点,就是其爆炸范围,即那个正方形的边必须和 <span id="MathJax-Span-28" class="mrow"><span id="MathJax-Span-29" class="mi">x<span id="MathJax-Span-30" class="texatom"><span id="MathJax-Span-31" class="mrow"><span id="MathJax-Span-32" class="mo">,<span id="MathJax-Span-33" class="mi">yx,y 轴平行。
求一颗炸弹最多能炸掉地图上总价值为多少的目标。
输入格式
第一行输入正整数 <span id="MathJax-Span-35" class="mrow"><span id="MathJax-Span-36" class="mi">NN 和 <span id="MathJax-Span-38" class="mrow"><span id="MathJax-Span-39" class="mi">RR,分别代表地图上的目标数目和正方形的边长,数据用空格隔开。
接下来 <span id="MathJax-Span-41" class="mrow"><span id="MathJax-Span-42" class="mi">NN 行,每行输入一组数据,每组数据包括三个整数 <span id="MathJax-Span-44" class="mrow"><span id="MathJax-Span-45" class="msubsup"><span id="MathJax-Span-46" class="mi">X<span id="MathJax-Span-47" class="texatom"><span id="MathJax-Span-48" class="mrow"><span id="MathJax-Span-49" class="mi">i<span id="MathJax-Span-50" class="mo">,<span id="MathJax-Span-51" class="msubsup"><span id="MathJax-Span-52" class="mi">Y<span id="MathJax-Span-53" class="texatom"><span id="MathJax-Span-54" class="mrow"><span id="MathJax-Span-55" class="mi">i<span id="MathJax-Span-56" class="mo">,<span id="MathJax-Span-57" class="msubsup"><span id="MathJax-Span-58" class="mi">W<span id="MathJax-Span-59" class="texatom"><span id="MathJax-Span-60" class="mrow"><span id="MathJax-Span-61" class="mi">iXi,Yi,Wi,分别代表目标的 <span id="MathJax-Span-63" class="mrow"><span id="MathJax-Span-64" class="mi">xx 坐标,<span id="MathJax-Span-66" class="mrow"><span id="MathJax-Span-67" class="mi">yy 坐标和价值,数据用空格隔开。
输出格式
输出一个正整数,代表一颗炸弹最多能炸掉地图上目标的总价值数目。
数据范围
输入样例:
2 1
0 0 1
1 1 1
输出样例:
1
注解:
本题主要运用二维前缀和的知识,不得不承认这个就是一个知识点,他的理解其实并没有太多的难度。
这里我们用其他人题解来进行理解,反正他不是太难;

1 //de一波二维前缀和 2 for (int i = 1; i <= 5001; i ++ ) 3 for (int j = 1; j <= 5001; j ++ ) 4 s[i][j] += s[i - 1][j] + s[i][j - 1] -s[i - 1][j - 1]; 5 //看图写公式xd 6 7 int res = 0; 8 for (int i = R; i <= 5001; i ++ ) 9 for (int j = R; j <= 5001; j ++ ) 10 res = max(res, s[i][j] - s[i - R][j] - s[i][j - R] + s[i - R][j - R]); 11 //i- (i - R) 是因为R个点只有R-1格个数,所有算R个点的面积就好了 12 //维护一波最大价值区间
接下来我么看AC代码,代码中用了两种方式
- 我们枚举右端点
- 我们枚举左端点
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 6 const int N = 5010; 7 int g[N][N]; 8 int n, r; 9 int main() { 10 11 cin >> n >> r; 12 r = min(r, 5001); 13 int X = r, Y = r; 14 for (int i = 0, x, y, w; i < n; i ++) { 15 cin >> x >> y >> w; 16 X = max(X, x + 1); 17 Y = max(Y, y + 1); 18 g[x + 1][y + 1] += w; 19 } 20 21 for (int i = 1; i <= X; i ++ ) { 22 for (int j = 1; j <= Y; j ++) { 23 g[i][j] += g[i][j - 1] + g[i - 1][j] - g[i - 1][j - 1]; 24 } 25 } 26 27 int res = 0; 28 29 // for (int i = r; i <= X; i ++ ) { 30 // for (int j = r; j <= Y; j ++) { 31 // 32 // 33 // res = max(res, g[i][j] - g[i - r][j] - g[i][j - r] + g[i-r][j-r]); 34 // 35 // } 36 // } 37 38 39 for (int i = 1; i + r - 1 <= X; i++) { 40 for (int j = 1; j + r - 1 <= Y; j++) { 41 res = max(res, g[i + r - 1][j + r - 1] - g[i - 1][j + r - 1] - g[i + r - 1][j - 1] + g[i - 1][j - 1]); 42 } 43 } 44 45 cout << res << endl; 46 return 0; 47 }

浙公网安备 33010602011771号