题目链接: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;
}