99.激光炸弹 | 前缀和
1 // 二维前缀和 2 #include <iostream> 3 #include <cmath> 4 using namespace std; 5 const int N = 5e3 + 10; 6 int n, a[N][N], r, SUM = 0; 7 int main() 8 { 9 cin >> n >> r; 10 int x, y, w; 11 int x_max = r, y_max = r; // 必须初始化为r 若初始化为0,则建立前缀和数组时无法进入循环(line:36) 12 for (int i = 0; i < n; i++) 13 { 14 scanf("%d%d%d", &x, &y, &w); 15 x++, y++; // 激光边界的正方形不会爆炸 16 a[x][y] += w; 17 SUM += w;//(line:24) 18 x_max = max(x_max, x); 19 y_max = max(y_max, y); 20 } 21 22 if (r > 5000)//数据加强过,需要加个特判:当激光"口径"大于坐标平面范围(0<=x,y<=5000)时,总的毁灭价值为SUM 23 { 24 cout << SUM << endl; 25 return 0; 26 }else{ 27 for (int i = 1; i <= x_max; i++) // 在a数组上直接建立前缀和数组 28 { 29 for (int j = 1; j <= y_max; j++) 30 { 31 a[i][j] += a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1]; 32 } 33 } 34 } 35 int res = 0; 36 for (int i = r; i <= x_max; i++) // 将所有的R*R小方阵遍历一遍 找最大毁灭价值 值得注意的是:i,j都从r开始遍历 37 { 38 for (int j = r; j <= y_max; j++) 39 { 40 res = max(res, a[i][j] - a[i][j - r] - a[i - r][j] + a[i - r][j - r]); 41 } 42 } 43 44 cout << res; 45 46 return 0; 47 }
posted on 2023-03-16 09:09 ShinnyBlue 阅读(24) 评论(0) 收藏 举报