N个点求最大的四边形面积

codeforces 340B Maximal Area Quadrilateral(叉积)

参考博客: http://www.cnblogs.com/zstu-abc/archive/2013/08/31/3293327.html
题意:平面上n个点(n<=300),问任意四个点组成的四边形(保证四条边不相交)的最大面积是多少。


分析:


1、第一思路是枚举四个点,以O(n4)的算法妥妥超时。


2、以下思路源自官方题解


  以O(n2)枚举每一条边,以这条边作为四边形的对角线(注意:这里所说的对角线是指把四边形分成两部分的线,不考虑凹四边形可能出现的两个点在对角线同一侧的情况),以O(n)枚举每一个点,判断是在对角线所在直线的左侧还是右侧。因为被对角线分割开的两三角形不相关,所以可以单独讨论:分别找出左右两侧的最大三角形,二者之和即为此边对应的最大四边形。整个算法为O(n3)。


3、何为叉积?


  百度百科“叉积”解释的很详细,这里用到两条:


  一、axb 表示的是一个符合右手法则的、垂直于a、b的向量c,|c|=|a|*|b|*sinθ,θ指向量a,b的夹角,即|c|是以a、b为边的平行四边形的面积——已知3点A,B,C,|BAxCA|==S(三角形ABC)*2。


  二、坐标表示法中,a(x1,y1),b(x2,y2)。c=axb=x1*y2-x2*y1,c的正负表示方向,正为上、负为下。而在三维中,方向不能简单的以正负表示,所以只能以一个向量的形式来描述:


  |  i , j , k |


  |x1,y1,z1|


  |x2,y2,z2|  i,j,k分别表示x轴、y轴、z轴上的单位向量,矩阵的解也就是c=axb。


  这里只是二维平面,判断点在向量所在直线的哪一侧,就可以利用叉积的方向来区别。对角线AB,两侧各取一点C、D,必然有CAxCB=-DAxDB。

代码:
#include 
#include 
#include 
#include 
#include 
using namespace std;
#define eps 1e-10

#define maxn 310
typedef struct point{
    double x,y;
}p;
p Point[maxn];

double cross(point p1,point p2,point p0){
    return ((p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x))*0.5;
}

double max(double a,double b){
    if(a>b) return a;
    return b;
}
int main()
{
    int n;
    while(~scanf("%d",&n)){
        for(int i=0;i


你可能感兴趣的:(040-数论)