2020HDU多校第一场-Leading Robots(贪心,单调栈)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6759

题意

T组输入
然后给您n个机器人的初始位置p和加速度a,问你有多少个机器人会出现领先于其他所有机器人的情况(注意是领先于其他所有)也就是说并行的两个是不可能出现领先的情况的。

思路

首先,我们先按加速度从小到大排序,再按初始位置从小到大排序。然后我们想,这样排序之后,那么后面的的机器人是一定会超过前面的机器人的,(因为,路无线长,加速度大的最终一定会超过加速度小的,如果加速度相同,那么后面的p大,那么在最开始就已经超过前面的了)这样的话,如果前面的初始位置小,那么就一定会被后面的淘汰(因为a[i+1]>=a[i]),这样我们就维护了一个位置单调递减的栈。同时我们还要考虑一种情况,就是栈中已经有机器人a,b,(说明b会在t1时间超过a并且开始时候a位置比b位置大,就是最开始a领先),现在来了一个c机器人,c位置比b小,也可以进栈,并且假设t2时间点超过b,如果t2<t1,那么b就被出栈,因为在b还没超a之前,就被c超了,那么b就不可能领先了呀。
然后判断栈中还有多少个机器人就行,还要进行map去重,因为相同的机器人是永远不可能单独领先于其他的。

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
#define fi first
#define se second
map<pii,int>v;
struct zxc
{
    double a,p;
}x[50015];
int st[50015];
bool cmp(zxc q,zxc w)
{
    if(q.a!=w.a)
    {
        return q.a<w.a;
    }
    else
    {
        return q.p<w.p;
    }
}
bool cx(zxc i,zxc j,zxc k)
{
    return (j.p-k.p)*(j.a-i.a)-(k.a-j.a)*(i.p-j.p)<=0;

}
int main()
{
//    freopen("D:\\1.in","r",stdin);
//    freopen("D:\\my.out","w",stdout);
    int t;
    scanf("%d",&t);
    while(t--)
    {
        v.clear();
        int n;
        scanf("%d",&n);
        pii w;
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&x[i].p,&x[i].a);
            w.fi=x[i].p;
            w.se=x[i].a;
            v[w]++;
        }
        sort(x+1,x+1+n,cmp);
        int tot=0;
        for(int i=1;i<=n;i++)
        {
            while((tot>0&&(x[i].p>=x[st[tot]].p))||(tot>1&&cx(x[st[tot-1]],x[st[tot]],x[i])))
            {
                tot--;
            }
            st[++tot]=i;
        }
        int ans=tot;
       for(int i=1;i<=tot;i++)
        {
           w.fi=x[st[i]].p;
           w.se=x[st[i]].a;
            if(v[w]>1)
            {
                ans--;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43402296/article/details/107547574