bzoj1069 [SCOI2007]最大土地面积

 

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

 

正解:凸包+旋转卡壳。

现在才学凸包和旋转卡壳,感觉自己真的太菜了。。

这道题还是比较简单的,首先我们可以想到这$4$个点一定在凸包上。那么我们可以枚举对角线,然后把这个四边形分成两个三角形。

然后用旋转卡壳算出两边对应最大的面积就行了。

 

 1 //It is made by wfj_2048~
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <cstring>
 5 #include <cstdlib>
 6 #include <cstdio>
 7 #include <vector>
 8 #include <cmath>
 9 #include <queue>
10 #include <stack>
11 #include <map>
12 #include <set>
13 #define eps (1e-9)
14 #define N (2010)
15 #define il inline
16 #define RG register
17 #define ll long long
18 
19 using namespace std;
20 
21 int n,top;
22 
23 struct point{ double x,y; }p[N],st[N];
24 
25 il point operator - (const point &a,const point &b){
26     return (point){a.x-b.x,a.y-b.y};
27 }
28 
29 il double cross(RG point a,RG point b){ return a.x*b.y-a.y*b.x; }
30 
31 il int cmp(const point &a,const point &b){
32     if (fabs(a.x-b.x)<eps) return a.y<b.y;
33     return a.x<b.x;
34 }
35 
36 il int gi(){
37     RG int x=0,q=1; RG char ch=getchar();
38     while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
39     if (ch=='-') q=-1,ch=getchar();
40     while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
41     return q*x;
42 }
43 
44 il double calc(){
45     RG double res=0;
46     for (RG int i=1,p1,p2;i<top;++i){
47     p1=p2=2;
48     for (RG int j=i+1;j<=top;++j){
49         while (cross(st[p1+1]-st[i],st[j]-st[i])>cross(st[p1]-st[i],st[j]-st[i])) p1=p1%top+1;
50         while (cross(st[j]-st[i],st[p2+1]-st[i])>cross(st[j]-st[i],st[p2]-st[i])) p2=p2%top+1;
51         res=max(res,cross(st[p1]-st[i],st[j]-st[i])+cross(st[j]-st[i],st[p2]-st[i]));
52     }
53     }
54     return res/2;
55 }
56 
57 int main(){
58 #ifndef ONLINE_JUDGE
59     freopen("square.in","r",stdin);
60     freopen("square.out","w",stdout);
61 #endif
62     n=gi();
63     for (RG int i=1;i<=n;++i) scanf("%lf%lf",&p[i].x,&p[i].y);
64     sort(p+1,p+n+1,cmp),st[++top]=p[1];
65     for (RG int i=2;i<=n;++i){
66     while (top>=2 && cross(st[top]-st[top-1],p[i]-st[top-1])<=0) --top;
67     st[++top]=p[i];
68     }
69     RG int la=top;
70     for (RG int i=n-1;i;--i){
71     while (top>la && cross(st[top]-st[top-1],p[i]-st[top-1])<=0) --top;
72     st[++top]=p[i];
73     }
74     st[top+1]=st[1],printf("%0.3lf\n",calc()); return 0;
75 }

 

posted @ 2017-08-01 09:21  wfj_2048  阅读(191)  评论(0编辑  收藏  举报