bzoj 1069 最大土地面积

题目大意:

一些点,选四个点使这围成的四边形面积最大

思路:

首先可以知道这些点一定在凸包上,然后graham求一下凸包

然后我们可以枚举对角线在两边找最远的点

然而这样复杂度爆了

所以我们可以利用旋转卡壳的思想

枚举对角线的时候确定一个点,然后旋转另一个点,如果确定了另外两个点,则另外两个点也一起转

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<set>
 6 #include<vector>
 7 #include<cmath>
 8 #include<algorithm>
 9 #define inf 2147483611
10 #define ll long long
11 using namespace std;
12 inline int read()
13 {
14     int x=0,f=1;char ch=getchar();
15     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
16     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
17     return x*f;
18 }
19 int n,top;
20 struct node
21 {
22     double x,y;
23     node operator - (const node &a) const
24     {
25         return (node) {x-a.x,y-a.y};
26     }
27     double operator * (const node &a) const
28     {
29         return x*a.y-y*a.x;
30     }
31 }pt[2005],st[2005];
32 double dis(node a,node b) {return hypot(fabs(a.x-b.x),fabs(a.y-b.y));}
33 bool cmp(node a,node b)
34 {
35     double t=(a-pt[1])*(b-pt[1]);
36     if(t==0)return dis(a,pt[1])<dis(b,pt[1]);
37     return t<0;
38 }
39 void G()
40 {
41     int k=1;
42     for(int i=2;i<=n;i++)
43         if(pt[k].y>pt[i].y||(pt[k].y==pt[i].y&&pt[k].x>pt[i].x)) k=i;
44     swap(pt[1],pt[k]);
45     sort(pt+2,pt+n+1,cmp);
46     st[++top]=pt[1];st[++top]=pt[2];
47     for(int i=3;i<=n;i++)
48     {
49         while(top>1&&(pt[i]-st[top-1])*(st[top]-st[top-1])<=0) top--;
50         st[++top]=pt[i];
51     }
52 }
53 int main()
54 {
55     n=read();
56     for(int i=1;i<=n;i++) scanf("%lf%lf",&pt[i].x,&pt[i].y);
57     G();
58     st[top+1]=pt[1];
59     double ans=0;
60     int l,r;
61     for(int i=1;i<=top;i++)
62     {
63         l=i%top+1;r=(i+2)%top+1;
64         for(int j=i+2;j<=top;j++)
65         {
66             while(l%top+1!=j&&(st[j]-st[i])*(st[l+1]-st[i])>(st[j]-st[i])*(st[l]-st[i])) l=l%top+1;
67             while(r%top+1!=i&&(st[r+1]-st[i])*(st[j]-st[i])>(st[r]-st[i])*(st[j]-st[i])) r=r%top+1;
68             ans=max((st[j]-st[i])*(st[l]-st[i])+(st[r]-st[i])*(st[j]-st[i]),ans);
69         }
70     }
71     printf("%.3lf",ans/2.0);
72     return 0;
73 }
74 
View Code
posted @ 2017-10-30 14:37  jack_yyc  阅读(163)  评论(0编辑  收藏  举报