HDU 6759 Leading Robots
//无证驾驶 #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; }