[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; }