BZOJ 1069: [SCOI2007]最大土地面积 旋转卡壳

来源:互联网 发布:js判断div是否有class 编辑:程序博客网 时间:2024/06/08 01:27

1069: [SCOI2007]最大土地面积

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


直接枚举对踵点 然后枚举左右两个点

苦苦调试好久 发现叉积竟然写错了。。后来又发现旋转卡壳启示


#include<cmath>#include<ctime>#include<cstdio>#include<cstring>#include<cstdlib>#include<iostream>#include<algorithm>#include<iomanip>#include<vector>#include<string>#include<bitset>#include<queue>#include<map>#include<set>using namespace std;typedef double db;typedef long long ll;inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}return x*f;}void print(int x){if(x<0)putchar('-'),x=-x;if(x>=10)print(x/10);putchar(x%10+'0');}const int N=2010,inf=0X3f3f3f3f;const db eps=1e-8;struct node{db x,y;friend db cross(const node &x,const node &y,const node &bas){db x1=x.x-bas.x,x2=y.x-bas.x;db y1=x.y-bas.y,y2=y.y-bas.y;return x1*y2-x2*y1;}friend db dis(const node &x,const node &y){return sqrt((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y));}}p[N];int n;inline bool cmp(const node &x,const node &y){db tmp=cross(x,y,p[1]);return tmp==0 ? dis(x,p[1])<dis(y,p[1]) : tmp<0;}int st[N],top;void graham(){register int i,tmp=1;for(i=1;i<=n;++i)if(p[i].x<p[tmp].x || (p[i].x==p[tmp].x&&p[i].y<p[tmp].y))tmp=i;swap(p[1],p[tmp]);sort(p+2,p+n+1,cmp);st[1]=1;st[2]=2;top=2;for(i=3;i<=n;++i){while(top>1&&cross(p[st[top]],p[i],p[st[top-1]])>-eps)top--;st[++top]=i;}st[++top]=1;}db ans;void RC(){register int i,now=2,j;for(i=1;i<top;++i){while( cross(p[st[now+1]],p[st[i+1]],p[st[i]])>cross(p[st[now]],p[st[i+1]],p[st[i]]) ){now++;if(now==top)now=1;}db tmp[2];tmp[0]=tmp[1]=0;j=i;while(j!=now){j++;if(j==top)j=1;tmp[0]=max( tmp[0],abs(cross(p[st[i]],p[st[now]],p[st[j]])) );}while(j!=i){j++;if(j==top)j=1;tmp[1]=max( tmp[1],abs(cross(p[st[i]],p[st[now]],p[st[j]])) );}ans=max(ans,(tmp[0]+tmp[1])*0.5);}}int main(){n=read();register int i;for(i=1;i<=n;++i)scanf("%lf%lf",&p[i].x,&p[i].y);graham();RC();printf("%.3lf\n",ans);}


阅读全文
0 0
原创粉丝点击