垃圾炸弹(二维前缀和)

时间:2021-05-02 23:23:24

题目描述

2014年足球世界杯(2014 FIFA World Cup)开踢啦!为了方便球迷观看比赛,街道上很多路口都放置了的直播大屏幕,但是人群散去后总会在这些路口留下一堆垃圾。为此*决定动用一种最新发明——“垃圾炸弹”。这种“炸弹”利用最先进的量子物理技术,爆炸后产生的冲击波可以完全清除波及范围内的所有垃圾,并且不会产生任何其他不良影响。炸弹爆炸后冲击波是以正方形方式扩散的,炸弹威力(扩散距离)以d给出,表示可以传播d条街道。
例如下图是一个d=1的“垃圾炸弹”爆炸后的波及范围。
垃圾炸弹(二维前缀和)
假设城市的布局为严格的[0,1024]*[0,1024]的网格状,由于财政问题市*只买得起一枚“垃圾炸弹”,希望你帮他们找到合适的投放地点,使得一次清除的垃圾总量最多(假设垃圾数量可以用一个非负整数表示,并且除设置大屏幕的路口以外的地点没有垃圾)。
 

输入

第一行给出“炸弹”威力d。第二行给出一个数组n表示设置了大屏幕(有垃圾)的路口数目。接下来n行每行给出三个数字x,y,i,分别代表路口的坐标(x,y)以及垃圾数量i。点坐标(x,y)保证是有效的(区间在0到1024之间),同一坐标只会给出一次。

输出

输出能清理垃圾最多的投放点数目,以及能够清除的垃圾总量。
 

样例输入

1
2
4 4 10
6 6 20

样例输出

1 30
 
此题主要考察二维数组前缀和;
初始化:
先for循环弄好两个坐标轴上的点;
再双重循环把全图补充上;
初始化代码:
 1 void bing(int x)
 2 {
 3     for(int i=1;i<=dd;i++)
 4     {
 5         s[i][0]=s[i-1][0]+a[i][0];
 6         s[0][i]=s[0][i-1]+a[0][i];
 7     }
 8         for(int i=1;i<=dd;i++)
 9         for(int j=1;j<=dd;j++)
10         s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
11     
12 }

然后全屏枚举,求某一区域面积方法如图(灵魂画作):

垃圾炸弹(二维前缀和)

注意两种特殊情况:

当i==d和j==d时,只需要减一个,具体请画图(边界);

思路代码:

 1 #include<bits/stdc++.h>
 2 #define dd 1025
 3 int d,n,x,y,z,t,a[1100][1100],s[1100][1100];
 4 int box[1100];
 5 void bing(int);
 6 int main()
 7 {
 8     freopen("boom.txt","r",stdin);
 9     memset(a,0,sizeof(a));
10     memset(s,0,sizeof(s));
11     memset(box,0,sizeof(box));
12     scanf("%d",&d);
13     scanf("%d",&n);
14     for(int i=1;i<=n;i++)
15     {
16         scanf("%d%d%d",&x,&y,&z);
17         a[x][y]=z;
18     }
19     bing(1);
20     for(int i=d;i<=dd;i++)
21     for(int j=d;j<=dd;j++)
22     {
23         if(i==d&&j==d)
24         {
25             int r=s[i+d][j+d];
26             box[r]++;
27             continue;
28         }
29         if(i==d&&j!=d)
30         {
31             int r=s[i+d][j+d]-s[i+d][j-d-1];
32             box[r]++;
33             continue;
34         }
35         if(j==d&&i!=d)
36         {
37             int r=s[i+d][j+d]-s[i-d-1][j+1];
38             box[r]++;
39             continue;
40         }
41         int r=s[i+d][j+d]-s[i-d-1][j+d]-s[i+d][j-d-1]+s[i-d-1][j-d-1];
42         if(r!=0)
43         box[r]++;
44     }
45     for(int i=1100;i>=1;i--)
46     if(box[i]>0)
47     {
48         printf("%d %d",box[i],i);
49         return 0;
50     }
51 }
52 void bing(int x)
53 {
54     for(int i=1;i<=dd;i++)
55     {
56         s[i][0]=s[i-1][0]+a[i][0];
57         s[0][i]=s[0][i-1]+a[0][i];
58     }
59         for(int i=1;i<=dd;i++)
60         for(int j=1;j<=dd;j++)
61         s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
62     
63 }