1069: [SCOI2007]最大土地面积
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 3673 Solved: 1454
[ 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
0 0
1 0
1 1
0 1
0.5 0.5
Sample Output
1.000
HINT
数据范围 n<=2000, |x|,|y|<=100000
Source
#include<cstdio>
#include<ctime>
#include<cstdlib>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
typedef double DL;
const int maxn = 2010;
const DL eps = 1e-9;
struct point{
DL x,y; point(DL x = 0,DL y = 0): x(x),y(y){}
};
struct Vector{
DL x,y; Vector(DL x = 0,DL y = 0): x(x),y(y){}
};
int n,top;
point p[maxn],stk[maxn];
inline int getint()
{
int ret = 0;
char c = getchar();
while (c < '0' || '9' < c) c = getchar();
while ('0' <= c && c <= '9')
ret = ret * 10 + c - '0',c = getchar();
return ret;
}
inline DL cross(Vector a,Vector b)
{
return a.x * b.y - b.x * a.y;
}
inline Vector link(point a,point b)
{
return (Vector){a.x - b.x,a.y - b.y};
}
inline DL sqr(DL x)
{
return x * x;
}
inline DL dis(point a,point b)
{
return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y));
}
inline bool cmp(point a,point b)
{
DL tmp = cross(link(a,p[1]),link(b,p[1]));
if (tmp == 0) return dis(a,p[1]) < dis(b,p[1]);
return tmp < 0;
}
inline void hull()
{
int to = 1;
for (int i = 2; i <= n; i++)
if (p[to].y > p[i].y || (p[to].y == p[i].y && p[to].x > p[i].x))
to = i;
swap(p[1],p[to]);
sort(p + 2,p + n + 1,cmp);
for (int i = 1; i <= n; i++)
{
while (top >= 2 && cross(link(p[i],stk[top - 1]),link(stk[top],stk[top - 1])) <= 0)
top--;
stk[++top] = p[i];
}
}
inline DL solve()
{
DL ans = 0;
for (int i = 1; i <= top; i++)
{
int a = i,b = i + 2;
for (int j = i + 2; j <= top; j++)
{
while (cross(link(stk[a % top + 1],stk[i]),link(stk[j],stk[i])) < cross(link(stk[a],stk[i]),link(stk[j],stk[i])))
a = a % top + 1;
while (cross(link(stk[b % top + 1],stk[j]),link(stk[i],stk[j])) < cross(link(stk[b],stk[j]),link(stk[i],stk[j])))
b = b % top + 1;
ans = max(ans, - cross(link(stk[a],stk[i]),link(stk[j],stk[i])) + cross(link(stk[b],stk[i]),link(stk[j],stk[i])));
}
}
return ans / 2;
}
int main()
{
n = getint();
for (int i = 1; i <= n; i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
hull();
printf("%.3lf",solve());
return 0;
}