【题解】HDU6759 Leading Robots (二维凸包)
根据高中的物理知识,(x={1over 2}at^2+p),所以建立一个(x-t^2)坐标系,每个车子的图像就变成了直线,直线去重后,答案=凸包大小。
如果有必要可以基数排序做到(O(n))。
//@winlere
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<vector>
using namespace std; typedef long long ll;
ll qr(){
ll ret=0,c=getchar(),f=0;
while(!isdigit(c)) f|=c==45,c=getchar();
while( isdigit(c)) ret=ret*10+c-48,c=getchar();
return f?-ret:ret;
}
const int maxn=50005;
typedef pair<ll,ll> P;
P data[maxn],sav[maxn];
bool ans[maxn],repeat[maxn];
int stk[maxn];
double operator * (P a,P b){
double ret=1.0*(b.second-a.second)/(a.first-b.first);
return ret;
}
void surface(int len){
int top=0;
for(int t=1,r=1;r<=len;t=++r){
while(r<len&&data[t].first==data[r+1].first) ++r;
t=r;
while(top&&data[stk[top]].second<=data[t].second) --top;
while(top>1&&data[stk[top]]*data[stk[top-1]]*data[t].first+data[t].second>=data[stk[top]]*data[stk[top-1]]*data[stk[top]].first+data[stk[top]].second) --top;
stk[++top]=t;
}
for(int t=1;t<=top;++t) ans[stk[t]]=1;
}
int main(){
int T=qr();
while(T--){
memset(ans,0,sizeof ans);
memset(repeat,0,sizeof repeat);
int n=qr(),len=0;
for(int t=1;t<=n;++t)
sav[t].second=qr()*2,sav[t].first=qr();
sort(sav+1,sav+n+1);
len=0;
for(int t=1,r=1;r<=n;t=++r){
while(r<n&&sav[r+1]==sav[t]) ++r;
data[++len]=sav[t];
if(r!=t) repeat[len]=1;
}
surface(len);
int ret=0;
for(int t=1;t<=len;++t)
if(ans[t]&&!repeat[t]) ++ret;
printf("%d
",ret);
}
return 0;
}