2020杭電多校第一場1009 Leading Robots 單調棧
阿新 • • 發佈:2020-07-22
http://acm.hdu.edu.cn/showproblem.php?pid=6759
題意:
有n個機器人,每個機器人有一個初始位置和加速度,同時向右移動,跑道很長,沒有終點。在某個特定時間,如果機器人是最右邊且唯一的,那麼它就是當時的領先機器人。問:領先機器人的數量。
題解:
參考部落格:https://blog.csdn.net/qq_44828887/article/details/107499606
加速度從小到排序,相同加速度位置從小到大排序,後面的機器人肯定可以超過前面的機器人(同加速度,同位置除外);
維護一個棧,棧中的機器人是領先機器人,當前入棧的機器人肯定可以超過棧中的機器人。
當後面(正要入棧的)機器人的位置大於等於前面(棧中)機器人的位置時,位置大的肯定會超過前一個(棧中)機器人,前一個機器人不可能是領先機器人,位置相等且加速度相同的機器人並行也不可能是領先機器人,所以出棧;
當棧中機器人>1時,如果棧頂前兩個機器人相遇的時間 大於 棧頂機器人和正要入棧的機器人相遇的時間,棧頂機器人出棧;
最後判斷棧中是否有並行機器人,有就減掉。
程式碼:
#include <bits/stdc++.h> using namespace std; const int MAXN=5e4+5; const int SIZE=5e4+5; const long long mod=998244353; typedef long long ll; //typedef __int128 LL; const int inf=0x3f3f3f3f; const long longView CodeINF=0x3f3f3f3f3f3f3f3f; int st[MAXN]; struct node { ll l,a; bool operator<(const node &Node)const{ if(a==Node.a)return l<Node.l; return a<Node.a; } }; node p[MAXN]; map<node,int>mp; bool check(node x,node y,node z) { return (y.l-z.l)*(y.a-x.a)-(x.l-y.l)*(z.a-y.a)<=0; } int main() { int t; scanf("%d",&t); while(t--) { mp.clear(); int n; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%lld%lld",&p[i].l,&p[i].a); mp[p[i]]++; } sort(p+1,p+1+n); int top=0; for(int i=1;i<=n;i++) { while((top>0&&p[i].l>=p[st[top]].l)||(top>1&&check(p[st[top-1]],p[st[top]],p[i])))--top; st[++top]=i; } int ans=top; for(int i=1;i<=top;i++) { if(mp[p[st[i]]]>1)ans--; } printf("%d\n",ans); } return 0; }