1. 程式人生 > >NOI:7213 垃圾炸彈

NOI:7213 垃圾炸彈

總時間限制: 1000ms 記憶體限制: 65536kB

描述

    2014年巴西世界盃(2014 FIFA World Cup)開踢啦!為了方便球迷觀看比賽,里約街道上很多路口都放置了的直播大螢幕,但是人群散去後總會在這些路口留下一堆垃圾。為此巴西政府決定動用一種最新發明——“垃圾炸彈”。這種“炸彈”利用最先進的量子物理技術,爆炸後產生的衝擊波可以完全清除波及範圍內的所有垃圾,並且不會產生任何其他不良影響。炸彈爆炸後衝擊波是以正方形方式擴散的,炸彈威力(擴散距離)以d給出,表示可以傳播d條街道。

    例如下圖是一個d=1的“垃圾炸彈”爆炸後的波及範圍。

    假設里約熱內盧市的佈局為嚴格的1025*1025的網格狀,由於財政問題市政府只買得起一枚“垃圾炸彈”,希望你幫他們找到合適的投放地點,使得一次清除的垃圾總量最多(假設垃圾數量可以用一個非負整數表示,並且除設定大螢幕的路口以外的地點沒有垃圾)。

輸入
第一行給出“炸彈”威力d(1 <= d <= 50)。第二行給出一個數組n(1 <= n <= 20)表示設定了大螢幕(有垃圾)的路口數目。接下來n行每行給出三個數字x, y, i, 分別代表路口的座標(x, y)以及垃圾數量i. 點座標(x, y)保證是有效的(區間在0到1024之間),同一座標只會給出一次。
輸出
輸出能清理垃圾最多的投放點數目,以及能夠清除的垃圾總量。
樣例輸入
124 4 106 6 20
樣例輸出
1 30

之前做這題就沒想到用一個數組記錄當前座標能處理到的炸彈。。。

之前一直想著先將垃圾記錄在陣列中,然後遍歷每個點,計算炸彈炸到的範圍內的垃圾數量,但是這樣很容易超時。

而這道題,神奇的是,垃圾周圍的點都可以作為炸彈,所以每次輸入垃圾的點,其周圍的點如果作為炸彈都可以獲取該點的垃圾值,這樣就不會超時了!

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<queue>
  4. #include<set>
  5. #include<algorithm>
  6. #include<map>
  7. #include<cstring>
  8. #include<cmath>
  9. usingnamespace std;  
  10. int ma[1050][1050]={0};  
  11. int main(){  
  12.     int
     d,n;  
  13.     cin>>d>>n;  
  14.     int maxn=0;  
  15.     for(int i=0;i<n;i++){  
  16.         int a,b,c;  
  17.         cin>>a>>b>>c;  
  18.         for(int j=0;j<1025;j++){  
  19.             for(int k=0;k<1025;k++){  
  20.                 int shang=j-d,xia=j+d,zuo=k-d,you=k+d;  
  21.                 if(a>=shang&&a<=xia&&b>=zuo&&b<=you){  
  22.                     ma[j][k]+=c;  
  23.                     if(ma[j][k]>maxn) maxn=ma[j][k];  
  24.                 }  
  25.             }  
  26.         }  
  27.     }   
  28.     int cnt=0;  
  29.     for(int i=0;i<1025;i++){  
  30.         for(int j=0;j<1025;j++)  
  31.         if(ma[i][j]==maxn) cnt++;  
  32.     }  
  33.     cout<<cnt<<" "<<maxn;  
  34.     return 0;  
  35. }