【BZOJ1069】【SCOI2007】最大土地面積 凸包 單調性
阿新 • • 發佈:2019-02-19
連結:
#include <stdio.h>
int main()
{
puts("轉載請註明出處[輾轉山河弋流歌 by 空灰冰魂]謝謝");
puts("網址:blog.csdn.net/vmurder/article/details/46591735");
}
題解:
先求凸包,然後:
列舉點
程式碼:
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 2050
#define eps 1e-7
using namespace std;
struct Point
{
double x,y;
void read(){scanf("%lf%lf",&x,&y);}
Point(double _x=0,double _y=0):x(_x),y(_y){}
bool operator < (const Point &A)const
{return x==A.x?y<A.y:x<A.x;}
double operator - (const Point &A)const
{return sqrt((x-A.x)*(x-A.x)+(y-A.y)*(y-A.y));}
}p[N],Zero;
int n;
double xmul(const Point &A,const Point &B,const Point &C)
{return (C.y-A.y)*(B.x-A.x)-(B.y-A.y)*(C.x-A.x);}
struct qiu_tu_bao
{// 名字就是這麼屌,不服你來打我啊
int stk1[N],top1,stk2[N],top2;
Point tp[N];
void work()
{
int i;
stk1[top1=1]=1;
for(i=2;i<=n;i++)
{
while(top1>1&&xmul(p[stk1[top1-1]],p[stk1[top1]],p[i])>-eps)top1--;
stk1[++top1]=i;
}
stk2[top2=1]=n;
for(i=n-1;i;i--)
{
while(top2>1&&xmul(p[stk2[top2-1]],p[stk2[top2]],p[i])>-eps)top2--;
stk2[++top2]=i;
}
n=0;
for(i=1;i<top1;i++)tp[++n]=p[stk1[i]];
for(i=1;i<top2;i++)tp[++n]=p[stk2[i]];
memcpy(p,tp,sizeof(Point)*(n+1));
}
}qtb;
int f[N][N];
#define rig(x,y) ((x+y - 1)%n+1)
#define lef(x,y) ((x-y+n-1)%n+1)
inline double Area(int l,int r,int x)
{
double ret=xmul(Zero,p[l],p[r]);
ret+=xmul(Zero,p[r],p[x]);
ret+=xmul(Zero,p[x],p[l]);
return ret;
}
inline bool check(int l,int r,int a,int b)
{return Area(l,r,a)<Area(l,r,b);}
int main()
{
int i,j,k;
int a,b,c;
Zero=Point(0,0);
scanf("%d",&n);
for(i=1;i<=n;i++)p[i].read();
sort(p+1,p+n+1);
qtb.work();
for(i=1;i<=n;i++)
{
f[i][rig(i,2)]=rig(i,1);
for(j=rig(i,3);rig(j,1)!=i;j=rig(j,1))
{
f[i][j]=f[i][lef(j,1)];
while(rig(f[i][j],1)!=j&&
check(i,j,f[i][j],f[i][j]+1))f[i][j]++;
}
}
double ans=0.0;
for(i=1;i<=n;i++)for(j=rig(i,2);rig(j,1)!=i;j=rig(j,1))
ans=max(ans,Area(i,j,f[i][j])+Area(i,f[j][i],j));
printf("%.3lf\n",ans/2.0);
return 0;
}