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
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 }