zoukankan      html  css  js  c++  java
  • codeforces 340B Maximal Area Quadrilateral(叉积)

    事实再一次证明:本小菜在计算几何上就是个渣= =

    题意:平面上n个点(n<=300),问任意四个点组成的四边形(保证四条边不相交)的最大面积是多少。

    分析:

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

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

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

    3、何为叉积?

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

      一、axb 表示的是一个符合右手法则的、垂直于ab的向量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

    注意:一开始不知道叉积的模即是三角形面积的两倍,就用axb=|a|*|b|*cosθ推S=|a|*|b|*sinθ,跑到第八组数据就超时了,纠结了好久,后来发现,原来每个三角形是在O(n3)的复杂度下求解的,多算一步就多一个O(n3),TLE的不冤T^T

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<algorithm>
     5 #define rep(i,a,b) for(int i=a;i<=b;i++)
     6 using namespace std;
     7 
     8 const int MAXN=333;
     9 const double eps=1e-10;
    10 
    11 struct Point{
    12     double x,y;
    13     Point(double _x=0,double _y=0):x(_x),y(_y){}
    14 }p[MAXN];
    15 
    16 typedef Point Vector;
    17 
    18 Vector operator - (Vector a,Vector b){return Vector(a.x-b.x,a.y-b.y);}
    19 
    20 double cross(Vector a,Vector b)
    21 {
    22     return (a.x*b.y-a.y*b.x)*0.5;
    23 }
    24 
    25 int main()
    26 {
    27     int n;
    28     scanf("%d",&n);
    29     rep(i,1,n){
    30         scanf("%lf%lf",&p[i].x,&p[i].y);
    31     }
    32     double ans=0;
    33     rep(i,1,n){
    34         rep(j,i+1,n){
    35             double lmax,rmax;
    36             lmax=rmax=0;
    37             rep(k,1,n){
    38                 if(k==i||k==j)
    39                     continue;
    40                 double s=cross(p[i]-p[k],p[j]-p[k]);
    41                 if(s<eps)
    42                     lmax=max(lmax,-s);
    43                 else
    44                     rmax=max(rmax,s);
    45             }
    46             if(lmax==0||rmax==0)
    47                 continue;
    48             ans=max(ans,lmax+rmax);
    49         }
    50     }
    51     printf("%f
    ",ans);
    52     return 0;
    53 }
    View Code
  • 相关阅读:
    HYSBZ 3813 奇数国
    HYSBZ 4419 发微博
    HYSBZ 1079 着色方案
    HYSBZ 3506 排序机械臂
    HYSBZ 3224 Tyvj 1728 普通平衡树
    Unity 3D,地形属性
    nginx 的naginx 种包含include关键字
    Redis 出现NOAUTH Authentication required解决方案
    mysql 8.0出现 Public Key Retrieval is not allowed
    修改jar包里的源码时候需要注意的问题
  • 原文地址:https://www.cnblogs.com/zstu-abc/p/3293327.html
Copyright © 2011-2022 走看看