1. 程式人生 > >ACM-ICPC 2018 青島賽區現場賽 K. Airdrop && ZOJ 4068 (暴力)

ACM-ICPC 2018 青島賽區現場賽 K. Airdrop && ZOJ 4068 (暴力)

題目連結:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4068

題意:吃雞遊戲簡化為二維平面上有 n 個人 (xi,yi),空投的位置在 (x0,y0),每一秒所有人向靠近空投的位置走一步,四個方向有優先順序先後(優先縱座標),若已經在空投的位置則不變。往空投位置移動過程中,若兩個或者更多人在同一點相遇(在空投相遇不算),則他們都死亡。給出空投的縱座標,詢問空投在所有橫座標中最少和最多存活的人數是多少。

題解:在最優情況下,空投的橫座標必然是某一個人的橫座標,因為這樣可以保證在該橫座標的人都不會死亡;而在最壞情況下,空投的橫座標則在兩個不同橫座標的人之間,若所有人橫座標都相差1,則空投橫座標也是某一個人的橫座標,所以需要考慮的橫座標最多隻有 2n 個。把橫座標排序後,分別從左往右掃一遍記錄每個點左邊存活的人數和從右往左掃一遍每個點右邊存活的人數即可,具體看程式碼~

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define ull unsigned long long
 5 #define mst(a,b) memset((a),(b),sizeof(a))
 6 #define mp(a,b) make_pair(a,b)
 7 #define pi acos(-1)
 8 #define pii pair<int,int>
 9 #define pb push_back
10 const int
INF = 0x3f3f3f3f; 11 const double eps = 1e-6; 12 const int MAXN = 1e5 + 10; 13 const int MAXM = 2e5 + 10; 14 const ll mod = 1e9 + 7; 15 16 int x[MAXN],y[MAXN]; 17 vector<int>p,vec[MAXN],ans; 18 int num[MAXM],sum[MAXM]; 19 20 int main() { 21 #ifdef local 22 freopen("data.txt", "r", stdin); 23
// freopen("data.txt", "w", stdout); 24 #endif 25 int t; 26 scanf("%d",&t); 27 while(t--) { 28 int n,y0; 29 scanf("%d%d",&n,&y0); 30 p.clear(); 31 p.push_back(0); 32 for(int i = 1; i <= n; i++) { 33 scanf("%d%d",&x[i],&y[i]); 34 vec[x[i]].clear(); 35 vec[x[i] + 1].clear(); 36 p.push_back(x[i]); 37 p.push_back(x[i] + 1); 38 } 39 sort(p.begin(),p.end()); 40 p.erase(unique(p.begin(),p.end()),p.end()); 41 for(int i = 1; i <= n; i++) vec[x[i]].push_back(y[i]); 42 int cnt = 0, pre = 0; 43 mst(sum, 0); 44 mst(num, 0); 45 for(int i = 0; i < p.size(); i++) { 46 int nx = p[i]; 47 sum[nx] = vec[nx].size(); 48 vector<int>temp; 49 for(int j = 0; j < vec[pre].size(); j++) { 50 int k = abs(1e5 + 1 - pre) + abs(y0 - vec[pre][j]); 51 num[k]++; 52 if(num[k] == 1) cnt++; 53 else temp.push_back(k); 54 } 55 for(int j = 0; j < temp.size(); j++) { 56 if(num[temp[j]]) cnt--; 57 num[temp[j]] = 0; 58 } 59 sum[nx] += cnt; 60 pre = p[i]; 61 } 62 ans.clear(); 63 mst(num, 0); 64 pre = cnt = 0; 65 for(int i = p.size() - 1; i >= 0; i--) { 66 int nx = p[i]; 67 vector<int>temp; 68 for(int j = 0; j < vec[pre].size(); j++) { 69 int k = abs(0 - pre) + abs(y0 - vec[pre][j]); 70 num[k]++; 71 if(num[k] == 1) cnt++; 72 else temp.push_back(k); 73 } 74 for(int j = 0; j < temp.size(); j++) { 75 if(num[temp[j]]) cnt--; 76 num[temp[j]] = 0; 77 } 78 sum[nx] += cnt; 79 ans.push_back(sum[nx]); 80 pre = p[i]; 81 } 82 sort(ans.begin(),ans.end()); 83 printf("%d %d\n",ans[0],ans[ans.size() - 1]); 84 } 85 return 0; 86 }