POJ 2187 Beauty Contest ——计算几何

貌似直接求出凸包之后$O(n^2)$暴力就可以了?

#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <stack>
#include <cmath>
using namespace std;
struct P{
	int x,y;
}p[50001];
P s[50001];
int top=0;
int ans=0;
inline long long dis(P a,P b)
{return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}
inline P operator-(const P &a,const P &b)
{return (P){a.x-b.x,a.y-b.y};}
inline long long operator*(const P &a,const P &b)
{return a.x*b.y-a.y*b.x;}
inline bool operator<(const P &a,const P &b)
{
	long long x=(a-p[1])*(b-p[1]);
	if (x==0) return dis(p[1],a)<dis(p[1],b);
	else return x<0;
}
int main()
{
	int n;
	scanf("%d",&n);
	for (int i=1;i<=n;++i) scanf("%d%d",&p[i].x,&p[i].y);
	int t=1;
	for (int i=1;i<=n;++i) if (p[i].y<p[t].y||(p[i].y==p[t].y&&p[i].x<p[t].x)) t=i;//扫描一遍,找到起始点 
	swap(p[1],p[t]);
	sort(p+2,p+n+1);
	s[++top]=p[1];s[++top]=p[2];
	for (int i=3;i<=n;++i)
	{
		while (top>=2&&(s[top]-s[top-1])*(p[i]-s[top-1])>=0) top--;
		s[++top]=p[i];
	}
	for (int i=1;i<=top;++i)
	  for (int j=1;j<=top;++j)
	  {
	  	if (i!=j)
	  	{
	  		int now=dis(s[i],s[j]);
	  		ans=max(now,ans);
		}
	  }
	printf("%d
",ans);
}

  

或者旋转卡壳。

网上许多参考都说旋转卡壳只需要转半圈。

但是显然是有反例的,有时候半圈是不可行的。

如果转一圈,貌似没有什么反例,就假装它是对的好了。

但是没有暴力快是smg?

#include <map>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define ll long long
#define eps 1e-8
#define mp make_pair

struct Point{
	int x,y;
	void print()
	{
		printf("Point (%d,%d)
",x,y);
	}
};

struct Vector{
	double x,y;
	void print()
	{
		printf("Vector (%.3f,%.3f)
",x,y);
	}
};

Vector operator - (Point a,Point b)
{Vector ret;ret.x=a.x-b.x;ret.y=a.y-b.y;return ret;}

double operator * (Vector a,Vector b)
{return a.x*b.y-a.y*b.x;}

bool cmp(Point a,Point b)
{return a.x==b.x?a.y<b.y:a.x<b.x;}

bool cmp2(Point a,Point b)
{
	if (a.x==b.x&&a.y==b.y) return 1;
	return 0;
}

int n,top,ans;
Point a[50005],sta[50005];

int dst(Point a,Point b)
{
	return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}

void Andrew()
{
	sta[++top]=a[1];
	F(i,2,n)
	{
		while (top>=2&&(sta[top]-sta[top-1])*(a[i]-sta[top])<eps) top--;
		sta[++top]=a[i];
	}
	int lower=top;
	D(i,n-1,1)
	{
		while (top-lower>=1&&(sta[top]-sta[top-1])*(a[i]-sta[top])<eps) top--;
		sta[++top]=a[i];
	}
//	F(i,1,top) sta[i].print();
//	F(i,1,top) F(j,1,top)
//		ans=max(ans,dst(sta[i],sta[j]));
}

void Rotating()
{
	int p=2;
	F(i,1,top-1)
	{
//		printf("!!!
");
//		sta[i].print();sta[i+1].print();
		int pnxt=(p+1); if (pnxt>top-1) pnxt-=top-1;
//		printf("%.6f %.6f
",(sta[p]-sta[i])*(sta[i+1]-sta[i]),(sta[p+1]-sta[i])*(sta[i+1]-sta[i]));
		while ((sta[i+1]-sta[i])*(sta[p]-sta[i])<(sta[i+1]-sta[i])*(sta[p+1]-sta[i]))
		{
			p=pnxt;
			pnxt++;
			if (pnxt>top-1) pnxt-=top-1;
		}
//		sta[p].print();
		ans=max(dst(sta[p],sta[i]),max(ans,dst(sta[p],sta[i+1])));
	}
}

int main()
{
//	freopen("in.txt","r",stdin);
	scanf("%d",&n);
	F(i,1,n) scanf("%d%d",&a[i].x,&a[i].y);
	sort(a+1,a+n+1,cmp);
	Andrew();
	Rotating();
	printf("%d
",ans);
}

  

原文地址:https://www.cnblogs.com/SfailSth/p/6687358.html