1069: [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
Sample Output
1.000
HINT
数据范围 n<=2000, |x|,|y|<=100000
【解题报告】
发现这是原来做过的原题。
记得当时最纠结的就是为啥这是n方而不是n三方。
后来想通了,因为枚举接踵点是单调的
代码如下:
/**************************************************************
Problem: 1069
User: onepointo
Language: C++
Result: Accepted
Time:280 ms
Memory:1292 kb
****************************************************************/
#include <bits/stdc++.h>
using namespace std;
struct Point
{
double x,y;
Point(long double _ = .0,long double __ = .0):x(_),y(__) {}
Point operator +(const Point &a)const
{return Point(x+a.x,y+a.y);}
Point operator -(const Point &a)const
{return Point(x-a.x,y-a.y);}
Point operator *(double a)const
{return Point(x*a,y*a);}
bool operator< (const Point& _P)const
{return y<_P.y||(y==_P.y&&x<_P.x);}
};
int n;
vector<Point> pts,cvx;
double cross(Point a,Point b)
{
return a.x*b.y-a.y*b.x;
}
double area(Point a,Point b,Point c)
{
return fabs(cross(b-a,c-a))/2.0;
}
bool onleft(Point a,Point b,Point p)
{
return cross(b-a,p-a)>0;
}
vector<Point> convex(vector<Point> pts)
{
int n=(int)pts.size();
sort(pts.begin(),pts.end());
vector<Point>stk;
int m=0;
for(int i=0;i<n;++i)
{
while(m>1&&!onleft(stk[m-2],stk[m-1],pts[i]))
{
m--;stk.pop_back();
}
m++;
stk.push_back(pts[i]);
}
int k=m;
for(int i=n-2;i>=0;--i)
{
while(m>k&&!onleft(stk[m-2],stk[m-1],pts[i]))
{
m--;stk.pop_back();
}
m++;
stk.push_back(pts[i]);
}
if(n>1)
{
m--;
stk.pop_back();
}
return stk;
}
double maxarea(vector<Point>cvx)
{
int n=(int)cvx.size();
vector <int> next(n,0);
for(int i=0;i<n;++i) next[i]=(i+1)%n;
if(n<=2) return 0.0;
if(n==3) return area(cvx[0],cvx[1],cvx[2]);
double ans=0.0;
for(int i=0;i<n;++i)
for(int j=next[next[i]],a=next[i],b=next[j];next[j]!=i;j=next[j])
{
while(area(cvx[i],cvx[a],cvx[j])<area(cvx[i],cvx[next[a]],cvx[j])) a=next[a];
while(area(cvx[j],cvx[b],cvx[i])<area(cvx[j],cvx[next[b]],cvx[i])) b=next[b];
ans=max(ans,area(cvx[i],cvx[a],cvx[j])+area(cvx[j],cvx[b],cvx[i]));
}
return ans;
}
int main()
{
int n;
scanf("%d",&n);
vector <Point> pts;
for(int i=0;i<n;++i)
{
double x,y;
scanf("%lf%lf",&x,&y);
pts.push_back(Point(x,y));
}
printf("%.3f\n",maxarea(convex(pts)));
return 0;
}

本文介绍了一种高效算法,用于解决给定平面上N个点时如何找出四点构成的最大多边形面积问题。通过计算几何的方法,如凸包构造与优化搜索策略,实现了O(N^2)的时间复杂度。
1141

被折叠的 条评论
为什么被折叠?



