【计算几何】【极角排序】Gym

把每件物品当成平面上一个点,将第一件物品放在原点。那个权重值相当于一条直线,于是相当于直线绕原点转一圈,统计上侧点的数量。

队友的代码:

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int xx,yy,n,num,minans,maxans,tx,ty,same,nowans;
struct node{
	int x,y,type;
}a[100005],b[100005];
bool cmp1(node a,node b)
{
	return a.x>b.x;
}
bool cmp2(node a,node b)
{
	return a.y>b.y;
}
bool cmp3(node a,node b)
{
	int yy1=a.y-yy;int yy2=b.y-yy;
	int xx1=a.x-xx;int xx2=b.x-xx;
	return yy1*xx2>yy2*xx1;
}
void ok(int p)
{
	minans=min(minans,p);
	maxans=max(maxans,p);
}
bool samer(int u,int v)
{
	return (a[u].x-xx)*(a[v].y-yy)==(a[u].y-yy)*(a[v].x-xx);
}
int main()
{
	minans=99999999;
	maxans=-1;
	scanf("%d",&n);
	scanf("%d%d",&xx,&yy);
	b[1].x=xx; b[1].y=yy;
	for(int i=2;i<=n;++i)
	{
		scanf("%d%d",&tx,&ty);
		b[i].x=tx; b[i].y=ty;
		if(tx>xx&&ty>yy)
		{
			
		}
		else if(tx<xx&&ty<yy)
		{
			
		}
		else if(tx<xx&&ty>yy)
		{
			a[++num].x=xx+(xx-tx);
			a[num].y=yy-(ty-yy);
			a[num].type=1;
		}
		else if(tx>xx&&ty<yy)
		{
			a[++num].x=tx;
			a[num].y=ty;
			a[num].type=2;
		}
		else if(tx==xx&&ty==yy)
		{
			same++;
		}
	}
	sort(b+1,b+n+1,cmp1);
	for(int i=1;i<=n;++i)
	if(b[i].x==xx)
	{
		ok(i);
	}
	sort(b+1,b+n+1,cmp2);
	for(int i=1;i<=n;++i)
	if(b[i].y==yy)
	{
		ok(i);
	}
	sort(a+1,a+num+1,cmp3);
	if(!num)
	{
		printf("%d %d",minans,maxans);
		return 0;
	}
	nowans=0;
	for(int i=1;i<=n;++i)
	if(b[i].x!=xx||b[i].y!=yy)
	{
		if(b[i].y==yy)
		{
			if(b[i].x>xx) nowans++;
		}
		else if(b[i].y>yy)
			nowans++;
	}
	int l=1,r=1;
	while(l<=num)
	{
		while(samer(l,r+1)&&r<num)
		{
			r++;
		}
		int now1=0,now2=0;
		for(int i=l;i<=r;++i)
		{
			if(a[i].type==1) now1++;
			else now2++;
		}
		ok(nowans+now2+same+1);
		ok(nowans-now1+1);
		nowans+=now2;
		nowans-=now1;
		l=r+1;
		r=l;
	}
	printf("%d %d",minans,maxans);
	return 0;
}
原文地址:https://www.cnblogs.com/autsky-jadek/p/7209805.html