●BZOJ 1069 [SCOI2007]最大土地面积
题链:
http://www.lydsy.com/JudgeOnline/problem.php?id=1069
题解:
计算几何,凸包,旋转卡壳
其实和这个题差不多,POJ 2079 Triangle
把四边形看出两个三角形就好了。
复杂度$O(N^2)$
代码:
#include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define MAXN 2050 using namespace std; const double eps=1e-8; int sign(double x){ if(fabs(x)<=eps) return 0; return x<0?-1:1; } struct Point{ double x,y; Point(double _x=0,double _y=0):x(_x),y(_y){} void Read(){scanf("%lf%lf",&x,&y);} }; typedef Point Vector; bool operator < (Point A,Point B){return sign(A.x-B.x)<0||(sign(A.x-B.x)==0&&sign(A.y-B.y)<0);} Vector operator - (Point A,Point B){return Vector(A.x-B.x,A.y-B.y);} double operator ^ (Vector A,Vector B){return A.x*B.y-A.y*B.x;} double operator * (Vector A,Vector B){return A.x*B.x+A.y*B.y;} Point D[MAXN],C[MAXN]; int Andrew(int dnt){ int cnt=0,k; sort(D+1,D+dnt+1); for(int i=1;i<=dnt;i++){ while(cnt>1&&sign((C[cnt]-C[cnt-1])^(D[i]-C[cnt-1]))<=0) cnt--; C[++cnt]=D[i]; } k=cnt; for(int i=dnt-1;i>=1;i--){ while(cnt>k&&sign((C[cnt]-C[cnt-1])^(D[i]-C[cnt-1]))<=0) cnt--; C[++cnt]=D[i]; } return cnt-(dnt>1); } double DA(Point P,Point P1,Point P2){//Directed_Area return fabs((P1-P)^(P2-P))/2; } double RC(int cnt){//Rotating_Calipers double S=0; C[cnt+1]=C[1]; for(int i=1,j,k1,k2;i<=cnt;i++){ k1=i%cnt+1; j=k1%cnt+1; k2=j%cnt+1; for(int cj=1;cj<=cnt-3;cj++,j=j%cnt+1){ while(sign(DA(C[k1],C[i],C[j])-DA(C[k1+1],C[i],C[j]))<=0) k1=k1%cnt+1; while(sign(DA(C[k2],C[i],C[j])-DA(C[k2+1],C[i],C[j]))<=0) k2=k2%cnt+1; S=max(S,DA(C[k1],C[i],C[j])+DA(C[k2],C[i],C[j])); } } return S; } int main(){ int n; scanf("%d",&n); for(int i=1;i<=n;i++) D[i].Read(); printf("%.3lf",RC(Andrew(n))); return 0; }
Do not go gentle into that good night.
Rage, rage against the dying of the light.
————Dylan Thomas