【题解】6759 Leading Robots (二维凸包)

【题解】HDU6759 Leading Robots (二维凸包)

根据高中的物理知识,\(x={1\over 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\n",ret);
	}
	return 0;
}


posted @ 2020-07-22 19:05  谁是鸽王  阅读(289)  评论(0编辑  收藏  举报