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
  • 相关阅读:
    暴破助攻提权:ruadmin
    Python 绝技 —— TCP服务器与客户端
    代码审计| HDWiki 漏洞(一)
    Android逆向——smali复杂类解析
    从外部入侵公司:外部渗透测试
    大脸猫讲逆向之ARM汇编中PC寄存器详解
    Ms17-010进行WEB提权之实践下某培训靶机服务器
    XSS钓鱼某网约车后台一探究竟,乘客隐私暴露引发思考
    python爬虫实践教学
    Swif语法基础 要点归纳(一)
  • 原文地址:https://www.cnblogs.com/zstu-abc/p/3293327.html
Copyright © 2011-2022 走看看