bzoj1069 [SCOI2007]最大土地面积(凸包+旋转卡壳)
2017-12-09 23:01
435 查看
bzoj1069 [SCOI2007]最大土地面积
原题地址:http://www.lydsy.com/JudgeOnline/problem.php?id=1069题意:
在某块平面土地上有N个点,你可以选择其中的任意四个点,将这片土地围起来,当然,你希望这四个点围成的多边形面积最大。
数据范围
n<=2000, |x|,|y|<=100000
题解:
首先,发现这四个点肯定都在凸包上,因为倘若一个点不在凸包上,肯定可以让凸包上一个点代替它,使面积更大。
暴力枚举4个点肯定是不行的。
于是考虑枚举对角线,然后寻找对角线两侧可以取到的最大三角形。
如果固定一个点,顺时针枚举对角线的另外一个点,发现与他们组成四边形的另两个点也是在顺时针移动的。
(想像用与枚举的整条对角线在两侧去卡这个凸包)
于是这是O(n^2)的。
代码:
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<cmath> #define Poi Vec using namespace std; const double EPS=1e-8; const int N=2005; struct Vec { double x,y; Vec(double x=0.0,double y=0.0):x(x),y(y) {} }P ,cvx ; Vec operator+(const Vec &A,const Vec &B) {return Vec(A.x+B.x,A.y+B.y);} Vec operator-(const Vec &A,const Vec &B) {return Vec(A.x-B.x,A.y-B.y);} Vec operator*(const Vec &A,double s) {return Vec(A.x*s,A.y*s);} Vec operator/(const Vec &A,double s) {return Vec(A.x/s,A.y/s);} double cross(const Vec &A,const Vec &B) {return A.x*B.y-B.x*A.y;} double dot(const Vec &A,const Vec &B) {return A.x*B.x+A.y*B.y;} bool cmp(const Vec &A,const Vec &B) {return (A.x!=B.x)?A.x<B.x:A.y<B.y;} bool onleft(Poi A,Poi B,Poi C) {return cross(B-A,C-A)>0;} int n,nxt ; int getcvx() { sort(P,P+n,cmp); int t=0; cvx[0]=P[0]; for(int i=1;i<n;i++) { while(t>0&&!onleft(cvx[t-1],cvx[t],P[i])) t--; cvx[++t]=P[i]; } int h=t; for(int i=n-2;i>=0;i--) { while(t>h&&!onleft(cvx[t-1],cvx[t],P[i])) t--; cvx[++t]=P[i]; } if(n>1) t--; return t+1; } double getarea(Poi A,Poi B,Poi C) {return fabs(cross(B-A,C-A))/2.0;} double getpoly() { if(n<=2) return 0; else if(n==3) return getarea(cvx[0],cvx[1],cvx[2]); double ans=0.0; for(int i=0;i<n;i++) nxt[i]=(i+1)%n; for(int i=0;i<n;i++) { for(int j=((i+1)%n+1)%n,a=(i+1)%n,b=(j+1)%n;(j+1)%n!=i;j=(j+1)%n)/// { while(getarea(cvx[i],cvx[a],cvx[j])<getarea(cvx[i],cvx[(a+1)%n],cvx[j])) a=(a+1)%n; while(getarea(cvx[j],cvx[b],cvx[i])<getarea(cvx[j],cvx[(b+1)%n],cvx[i])) b=(b+1)%n; ans=max(ans,getarea(cvx[i],cvx[a],cvx[j])+getarea(cvx[j],cvx[b],cvx[i])); } } return ans; } int main() { scanf("%d",&n); for(int i=0;i<n;i++) {double x,y; scanf("%lf%lf",&x,&y); P[i]=Vec(x,y);} n=getcvx(); double ans=getpoly(); printf("%0.3lf\n",ans); return 0; }
相关文章推荐
- [BZOJ 1069][SCOI 2007]最大土地面积(凸包+旋转卡壳)
- bzoj 1069: [SCOI2007]最大土地面积 凸包+旋转卡壳
- [BZOJ1069][SCOI2007]最大土地面积 凸包+旋转卡壳
- [BZOJ1069][SCOI2007]最大土地面积(凸包+旋转卡壳)
- 【bzoj1069】[SCOI2007]最大土地面积 凸包+旋转卡壳
- [Bzoj1069][Scoi2007]最大土地面积(凸包)(旋转卡壳)
- 【BZOJ 1069】【SCOI 2007】最大土地面积 凸包+旋转卡壳
- BZOJ1069 [SCOI2007]最大土地面积 【凸包 + 旋转卡壳】
- [BZOJ1069]SCOI2007最大土地面积|凸包|旋转卡壳
- 【BZOJ】1069: [SCOI2007]最大土地面积(凸包+旋转卡壳)
- BZOJ 1069: [SCOI2007]最大土地面积 凸包,旋转卡壳
- BZOJ 1069 [SCOI 2007] 最大土地面积 (凸包+旋转卡壳)
- [BZOJ1069][SCOI2007][凸包][旋转卡壳]最大土地面积
- BZOJ 1069 SCOI 2007 最大土地面积 凸包+旋转卡壳
- [BZOJ]1069 [SCOI2007] 最大土地面积 凸包 + 旋转卡壳
- BZOJ 1069: [SCOI2007]最大土地面积 旋转卡壳
- BZOJ 1069 SCOI2007 最大土地面积 旋转卡壳
- BZOJ 1069 [SCOI2007]最大土地面积 旋转卡壳
- BZOJ 1069: [SCOI2007]最大土地面积 [旋转卡壳]
- [省选前题目整理][BZOJ 1069][SCOI 2007]最大土地面积(旋转卡壳)