ACM-ICPC 2018 青岛赛区现场赛 K. Airdrop && ZOJ 4068 (暴力)
Posted scaulok
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 ",ans[0],ans[ans.size() - 1]); 84 } 85 return 0; 86 }
以上是关于ACM-ICPC 2018 青岛赛区现场赛 K. Airdrop && ZOJ 4068 (暴力)的主要内容,如果未能解决你的问题,请参考以下文章
ACM-ICPC 2016 大连赛区现场赛 K. Guess the number && HDU 5981
2017 ACM-ICPC 亚洲区(青岛赛区)网络赛 1001
2017 ACM-ICPC 亚洲区(青岛赛区)网络赛 1003