1. 程式人生 > 實用技巧 >(字首和)鐳射炸彈

(字首和)鐳射炸彈

題目連結

根據題意畫出格點,觀察到到當正方形恰好和圖形的邊框重合時,設小正方形的邊長為R,

那麼此時圈中的點組成的方形的長度為(R-1)*(R-1),也就是(R - 1)* ( R - 1)個點,而假

如將大的方形稍微挪動一點到第二張圖片所示位置,那麼就能圈中R * R個點。

還有需要注意的一點就是由於題目給的正方形長度為1e9,而點的最大值為5000,所以需要

求出點的最大值並將其作為新的正方形的長和寬。

另外,本體主要是考察二維字首和演算法,對於二位字首和,

假如有二維陣列 a 以及二維字首和陣列 sum, 那麼 sum[ i ] [ j ] = sum[ i - 1][ j ] + sum[ i ] [ j - 1] + a [ i ] [ j ] - sum[ i - 1] [ j - 1]

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 using namespace std;
 5 int n, cnt, r, m;
 6 int sum[5010][5010];
 7 int main(){
 8     cin >> cnt >> r;
 9     int x, y, v;
10     r = min(5001, r);
11     n = m = r;
12     for (int i = 1; i <= cnt; i ++) {
13 scanf("%d %d %d", &x, &y, &v); 14 x++, y++; 15 n = max(n, x), m = max(m, y); 16 sum[x][y] += v; 17 } 18 for (int i = 1; i <= n; i ++){ 19 for(int j = 1; j <= m; j ++){ 20 sum[i][j] += sum[i - 1][j] + sum[i][j - 1] - sum[i - 1
][j - 1]; 21 } 22 } 23 int maxn = -1; 24 for(int i = r; i <= n; i ++){ 25 for(int j = r; j <= m; j ++){ 26 maxn = max(sum[i][j] - sum[i - r][j] - sum[i][j - r] + sum[i - r][j - r], maxn); 27 } 28 } 29 cout << maxn << endl; 30 return 0; 31 }