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\n",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)\n",x,y); } }; struct Vector{ double x,y; void print() { printf("Vector (%.3f,%.3f)\n",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("!!!\n"); // sta[i].print();sta[i+1].print(); int pnxt=(p+1); if (pnxt>top-1) pnxt-=top-1; // printf("%.6f %.6f\n",(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\n",ans); }