Time Limit: 1 Sec Memory Limit: 128 MB
[Submit][Status][Discuss]
Description
在某块平面土地上有N个点,你可以选择其中的任意四个点,将这片土地围起来,当然,你希望这四个点围成
的多边形面积最大。
Input
第1行一个正整数N,接下来N行,每行2个数x,y,表示该点的横坐标和纵坐标。
Output
最大的多边形面积,答案精确到小数点后3位。
Sample Input
5
0 0
1 0
1 1
0 1
0.5 0.5
Sample Output
1.000
HINT
数据范围 n<=2000, |x|,|y|<=100000
暴力:20
正解:
要找最大的四边形面积,那么这个点一定在凸包上(因为面积最大,所以点越分散越好,而凸包是最外围最分散的点)
那么我们就可以先求出凸包,然后枚举一个对角线,将凸包分成两部分,两部分
最大的三角形面积之和即为所需的可能答案。
用旋转卡壳维护对角线一侧三角形面积最大的点。
加油。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #define DB double 5 #include<cmath> 6 #define eps 1e-8 7 using namespace std; 8 const int N=2010; 9 struct node{ 10 DB x,y; 11 }d[N],s[N]; 12 bool cmp1(node a,node b) 13 { 14 if(a.y!=b.y) return a.y<b.y; 15 else return a.x<b.x; 16 } 17 DB dis(node a,node b) 18 { 19 return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); 20 } 21 DB cross(node a,node b,node c){return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);} 22 bool cmp2(node a,node b) 23 { 24 int m=cross(d[1],a,b); 25 if(m>eps) return 1; 26 else if(m==0) return dis(d[1],a)+eps<=dis(d[1],b); 27 else return 0; 28 } 29 int n,top; 30 DB ans; 31 DB S(node a,node b,node c) 32 { 33 DB X1=dis(a,b),X2=dis(a,c),X3=dis(b,c); 34 DB p=(X1+X2+X3)/2.0; 35 return sqrt(p*(p-X1)*(p-X2)*(p-X3)); 36 } 37 void getans() 38 { 39 s[top+1]=s[1]; 40 for(int i=1;i<=top;++i) 41 { 42 int a=i%top+1,b=(i+2)%top+1; 43 for(int j=i+2;j<=top;++j) 44 { 45 while(a%top+1!=j && S(s[i],s[j],s[a])<S(s[i],s[j],s[a+1])) (a%=top)+=1; 46 while(b%top+1!=j&& S(s[i],s[j],s[b])<S(s[i],s[j],s[b+1])) (b%=top)+=1; 47 ans=max(ans,S(s[i],s[j],s[a])+S(s[i],s[j],s[b])); 48 } 49 } 50 printf("%.3lf",ans); 51 } 52 int main() 53 { 54 scanf("%d",&n); 55 for(int i=1;i<=n;++i) 56 scanf("%lf%lf",&d[i].x,&d[i].y); 57 sort(d+1,d+n+1,cmp1); 58 s[++top]=d[1]; 59 sort(d+2,d+n+1,cmp2); 60 s[++top]=d[2]; 61 for(int i=3;i<=n;++i) 62 { 63 while(top>=2 && cross(s[top-1],s[top],d[i])<=0) top--; 64 s[++top]=d[i]; 65 } 66 getans(); 67 return 0; 68 }
达人观物外之物,思身后之身,宁受一时之寂寞,毋取万古之凄凉。