在某块平面土地上有N个点,你可以选择其中的任意四个点,将这片土地围起来,当然,你希望这四个点围成
的多边形面积最大。
标签:
在某块平面土地上有N个点,你可以选择其中的任意四个点,将这片土地围起来,当然,你希望这四个点围成
的多边形面积最大。
第1行一个正整数N,接下来N行,每行2个数x,y,表示该点的横坐标和纵坐标。
最大的多边形面积,答案精确到小数点后3位。
数据范围 n<=2000, |x|,|y|<=100000
先求个凸包,然后枚举对角线,两边找面积最大的三角形
1 /*by SilverN*/ 2 #include<iostream> 3 #include<cstdio> 4 #include<cmath> 5 #include<cstring> 6 #include<algorithm> 7 #define ll long long 8 using namespace std; 9 const int mxn=3000; 10 struct P{ 11 double x,y; 12 }p[mxn],s[mxn]; 13 int top=0; 14 int n; 15 double ans=0; 16 // 17 inline P operator - (P a,P b){ 18 P t; t.x=a.x-b.x; t.y=a.y-b.y; return t; 19 } 20 inline double operator * (P a,P b){ 21 return (a.x*b.y)-(b.x*a.y); 22 } 23 inline double dis(P a,P b){ 24 return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y); 25 } 26 inline bool operator < (P a,P b){ 27 double t=(a-p[1])*(b-p[1]); 28 if(t==0)return dis(a,p[1])<dis(b,p[1]); 29 return t<0; 30 } 31 // 32 void graham(){ 33 int t=1; 34 int i,j; 35 for(i=2;i<=n;i++){ 36 if(p[i].y<p[t].y || (p[i].y==p[t].y && p[i].x<p[t].x))t=i; 37 } 38 swap(p[1],p[t]); 39 sort(p+2,p+n+1); 40 s[++top]=p[1];s[++top]=p[2]; 41 for(i=3;i<=n;i++){ 42 while(top>1 && (p[i]-s[top-1])*(s[top]-s[top-1])<=0) 43 top--; 44 s[++top]=p[i]; 45 } 46 s[top+1]=p[1]; 47 return; 48 } 49 double solve() 50 { 51 s[top+1]=p[1]; 52 double ans=0; 53 int a,b; 54 for(int x=1;x<=top;x++) 55 { 56 a=x%top+1;b=(x+2)%top+1; 57 for(int y=x+2;y<=top;y++) 58 { 59 while(a%top+1!=y&&(s[y]-s[x])*(s[a+1]-s[x])>(s[y]-s[x])*(s[a]-s[x])) 60 a=a%top+1; 61 while(b%top+1!=x&&(s[b+1]-s[x])*(s[y]-s[x])>(s[b]-s[x])*(s[y]-s[x])) 62 b=b%top+1; 63 ans=max((s[y]-s[x])*(s[a]-s[x])+(s[b]-s[x])*(s[y]-s[x]),ans);//(s[b]-s[x])*(s[y]-s[x])前后颠倒成(s[y]-s[x])*(s[b]-s[x])就会WA,不能理解 64 } 65 } 66 return ans; 67 } 68 int main(){ 69 scanf("%d",&n); 70 int i,j; 71 for(i=1;i<=n;i++){ 72 scanf("%lf%lf",&p[i].x,&p[i].y); 73 } 74 graham(); 75 printf("%.3lf\n",solve()/2); 76 return 0; 77 }
标签:
原文地址:http://www.cnblogs.com/SilverNebula/p/5572642.html