参考博文:https://blog.csdn.net/qq_43402296/article/details/107547574?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param
![]()
//无证驾驶
#include<bits/stdc++.h>
#define mem(a) memset(a,0,sizeof(a))
#define forn(i,n) for(int i=0;i<n;++i)
#define for1(i,n) for(int i=1;i<=n;++i)
#define IO std::ios::sync_with_stdio(false); std::cin.tie(0)
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=1e7+50;
const int mod=1e9+7;
int n,t;
struct node
{
ll a,p;
}a[50005],b[50005],c[50005];
//这里是按照加速度优先,位置其次来进行排序
bool cmp(node x,node y)
{
if(x.a==y.a) return x.p>y.p;
return x.a>y.a;
}
//计算robot x追上robot y所用的时间,高中物理公式
double ft(node x,node y)
{
double dis=2.0*(y.p-x.p);
double ans=dis/(1.0*(x.a-y.a));
return ans;
}
int main()
{
IO;
cin>>t;
while(t--)
{
map<int,map<int,int>> mp;
cin>>n;
for1(i,n)
{
cin>>a[i].p>>a[i].a;
mp[a[i].p][a[i].a]++;
}
sort(a+1,a+n+1,cmp);
//这里进行筛选,只选择那些有可能成为第一的robot,就是在加速度在变小的情况下,位置在前面的
int h=1;
b[h]=a[1];
for(int i=2;i<=n;++i)
{
if(a[i].p>b[h].p)
{
b[++h]=a[i];
}
}
//这里就是计算每一个robot能不能成为第一
int k=1;
c[k]=b[h];
for(int i=h-1;i>=1;--i)
{
//只有一个的时候,后面的一定能成为第一
if(k<=1)
{
c[++k]=b[i];
continue;
}
while(k>=2)
{
//如果不能在前一个追上在前一个之前追上前一个,那就直接放进栈中,因为它能成为第一个,只不过是在它前一个之后
if(ft(b[i],c[k])>ft(c[k],c[k-1]))
break;
else//否则就说明前一个没法成为第一个,因为在路上就被超了
k--;
}
c[++k]=b[i];
}
//最后统计有几个能够成为第一个
int ans=0;
for1(i,k)
{
if(mp[c[i].p][c[i].a]==1)
ans++;
}
cout<<ans<<"\n";
}
return 0;
}