1. 程式人生 > 實用技巧 >[2020杭電多校第一場]1009 Leading Robots

[2020杭電多校第一場]1009 Leading Robots

首先,考慮一輛車能追上另一輛車的前提是前者加速度大於後者並且初始位置小於後者。那麼按照加速度從大到小排序,加速度相同則按照初始位置從大到小排序。然後順序遍歷,按照初始位置遞增的方式取出若干車子。我們現在保證了後面的車子一定能追上前面的車子,即車b一定能追上車a,而這時候如果進來一輛車c,如果車c追上車b的時間小於等與車b追上a的時間,那麼b永遠不可能當第一。那麼n輛車我都按照這種方式O(n)掃一遍,即可得到最終哪些車會是第一名。(這裡感覺有點單調棧的思想)。注意開始的時候用map標記一下a和p都相同的車子,最後統計答案的時候不能算進去(並列不算第一)。

#include<bits/stdc++.h>
#define
ll long long #define PB push_back #define endl '\n' #define INF 0x3f3f3f3f #define LINF 0x3f3f3f3f3f3f3f3f #define ull unsigned long long #define lson rt << 1, l, mid #define rson rt << 1 | 1, mid + 1, r #define lowbit(x) (x & (-x)) #define rep(i, a, b) for(int i = a ; i <= b ; ++ i) #define
per(i, a, b) for(int i = b ; i >= a ; -- i) #define clr(a, b) memset(a, b, sizeof(a)) #define in insert #define random(x) (rand()%x) #define PII(x, y) make_pair(x, y) #define fi first #define se second #define pi acos(-1) using namespace std; const int maxn = 2e6 + 1000; const ll mod = 998244353; int
T, n; struct node{ ll a, p; friend bool operator < (node a, node b){ return a.a == b.a ? a.p > b.p : a.a > b.a; } }c[maxn], b[maxn], d[maxn]; double f(node a, node b){ return (a.p-b.p)*1.0/(b.a-a.a); } signed main(){ cin >> T; while(T --){ map<pair<int,int>, int> mp; scanf("%d", &n); rep(i, 1, n){ scanf("%lld %lld", &c[i].a, &c[i].p); mp[PII(c[i].a, c[i].p)] ++; } sort(c + 1, c + 1 + n); ll tmp = c[1].p, k = 0; b[++k] = c[1]; for(int i = 2 ; i <= n ; ++ i){ if(c[i].p > tmp){ tmp = c[i].p; b[++k] = c[i]; } } int cnt = 0; per(i, 1, k){ while(cnt >= 2){ if(f(b[i], d[cnt]) <= f(d[cnt], d[cnt-1])) cnt --; else break; } d[++cnt] = b[i]; } int ans = 0; rep(i, 1, cnt) if(mp[PII(d[i].a, d[i].p)] == 1) ans ++; cout << ans << endl; } return 0; }
View Code