2020杭电多校第一场(解题报告)

1009 Leading Robots

题意:给你n个机器小车,和他们的初始位置p和加速度a,初始速度都是0,时间无限量,同时向右行驶,问你在行驶过程中有多少辆小车会处于领先位置?并行驱使不算领先。

 输入:

1
3
1 1
2 3
3 2

输出:

2

hint:单调栈的做法。

先将所有小车按照加速度从小到大的顺序排列,加速度相同时按照初始位置从小到大排列。如此以来,后面的车都能超越前面的车。所以维护一个栈,(栈中:栈顶。栈前:栈顶前一个位置。后车:要入栈的车子。)存放领先的车子,后面的车子肯定能超越栈中的车子,但是当后面车子的初始位置大于栈中车子时,栈中车子肯定不会领先了,所以出栈。当后车超越栈中的车的时间小于栈中车子超越栈前车子时,说明栈中的车也不会领先了,所以也出栈,比较时间的方法如下。特别注意的一点就是当初始位置和加速度都一样的车子如果处于领先位置的话,那么不算一种,所以可以用map记录一下领先的车子,并去重。

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 50500;
struct node{
    LL a,p;
    bool operator <  (const node &b)const{
        return a < b.a || (a == b.a && p < b.p);
    }
}robot[N];
map<node,int>mp;
int s[N];
bool check(node x,node y,node z){
    return (x.p-y.p)*(y.a-z.a)>=(y.p-z.p)*(x.a-y.a);
}
int main(){
    int t;scanf("%d",&t);
    while(t--){
        mp.clear();
        int n;scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%lld%lld",&robot[i].p,&robot[i].a);
            mp[robot[i]]++;
        }
        sort(robot,robot+n);
        int top=0;
        for(int i=0;i<n;i++){
            while((top>0&&robot[s[top]].p<=robot[i].p)||(top>1&&check(robot[i],robot[s[top]],robot[s[top-1]])))top--;
            s[++top]=i;
        }
        int ans=top;
        for(int i=1;i<=top;i++){
            if(mp[robot[s[i]]]>1)ans--;
        }
        cout<<ans<<endl;
    }
    system("pause");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43911947/article/details/107530307