1. 程式人生 > >[BZOJ1069][SCOI2007]最大土地面積 凸包+旋轉卡殼

[BZOJ1069][SCOI2007]最大土地面積 凸包+旋轉卡殼

splay col 答案 sam scrip sample per submit names

1069: [SCOI2007]最大土地面積

Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 3669 Solved: 1451
[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

技術分享
 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<algorithm>
 7 #define eps 1e-9
 8 using namespace std;
 9 struct point {
10     double x,y;
11 bool operator <(const point t) const { 12 return fabs(t.x-x)>eps?x<t.x:y<t.y; 13 } 14 }p[2500],s[2500]; 15 point operator -(point t1,point t2) { 16 return (point){t1.x-t2.x,t1.y-t2.y}; 17 } 18 double operator *(point t1,point t2) { 19 return t1.x*t2.y-t2.x*t1.y; 20 }
21 int n,top; 22 void get() { 23 s[0]=p[1]; 24 for(int i=2;i<=n;i++) { 25 while(top&&(s[top]-s[top-1])*(p[i]-s[top])>=0) top--; 26 s[++top]=p[i]; 27 } 28 int tmp=top; 29 for(int i=n-1;i>=1;i--) { 30 while(top>tmp&&(s[top]-s[top-1])*(p[i]-s[top])>=0) top--; 31 s[++top]=p[i]; 32 } 33 } 34 double cnts(point a,point b,point c) { 35 return fabs((b-a)*(c-a))/2; 36 } 37 int main() { 38 double maxn=0; 39 scanf("%d",&n); 40 for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y); 41 sort(p+1,p+n+1); 42 get(); 43 for(int i=0;i<top;i++) { 44 int j=(i+2)%top,k=(i+1)%top,w=(j+1)%top; 45 while(cnts(s[i],s[j],s[k])<cnts(s[i],s[j],s[k+1])) k=(k+1)%top; 46 double ans1=cnts(s[i],s[j],s[k]); 47 while(cnts(s[i],s[j],s[w])<cnts(s[i],s[j],s[w+1])) w=(w+1)%top; 48 double ans2=cnts(s[i],s[j],s[w]); 49 double ans=0; 50 while(ans1+ans2>ans) { 51 ans=ans1+ans2; 52 j=(j+1)%top; 53 while(cnts(s[i],s[j],s[k])<cnts(s[i],s[j],s[k+1])) k=(k+1)%top; 54 ans1=cnts(s[i],s[j],s[k]); 55 while(cnts(s[i],s[j],s[w])<cnts(s[i],s[j],s[w+1])) w=(w+1)%top; 56 ans2=cnts(s[i],s[j],s[w]); 57 } 58 maxn=max(maxn,ans); 59 } 60 printf("%.3lf",maxn); 61 }
View Code

[BZOJ1069][SCOI2007]最大土地面積 凸包+旋轉卡殼