zoukankan      html  css  js  c++  java
  • (hdu step 7.1.6)最大三角形(凸包的应用——在n个点中找到3个点,它们所形成的三角形面积最大)

    题目:

    最大三角形

    Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 121 Accepted Submission(s): 61
     
    Problem Description
    老师在计算几何这门课上给Eddy布置了一道题目。题目是这种:给定二维的平面上n个不同的点,要求在这些点里寻找三个点。使他们构成的三角形拥有的面积最大。
    Eddy对这道题目百思不得其解,想不通用什么方法来解决,因此他找到了聪明的你,请你帮他解决这个题目。
     
    Input
    输入数据包括多组測试用例。每一个測试用例的第一行包括一个整数n。表示一共同拥有n个互不同样的点,接下来的n行每行包括2个整数xi,yi。表示平面上第i个点的x与y坐标。

    你能够觉得:3 <= n <= 50000 并且 -10000 <= xi, yi <= 10000.

     
    Output
    对于每一组測试数据,请输出构成的最大的三角形的面积。结果保留两位小数。


    每组输出占一行。


     
    Sample Input
    3
    3 4
    2 6
    3 7
    6
    2 6
    3 9
    2 0
    8 0
    6 6
    7 7
     
    Sample Output
    1.50
    27.00
     
    Author
    Eddy
     
     
    Recommend
    lcy
     


    题目分析:

                 凸包的简单应用,在n个点中找到3个点,它们所形成的三角形面积最大。

    这道题一般来说有两种思路:

    1)直接暴力。这肯定会TLE,由于n的数据范围都在50000左右了。

    2)先求凸包。

    然后再在凸包上去找这三个点。这种话,数据规模就要小非常多了。事实证明,能形成最大三角形的

    这三个点也一定在凸包上。


    代码例如以下:

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    
    using namespace std;
    
    /**
     * 求n个点中随意三个点所形成的三角形的最大面积。
     * 1)直接暴力。

    肯定会TLE。

    由于n都是50000多了。

    * * 2)所形成的最大三角形的三个点肯定在凸包上。

    在凸包上找这三个点 * 将问题转化成: * 在凸包上求三个点所形成的三角形的面积最大.. */ const double epsi = 1e-8; const double pi = acos(-1.0); const int maxn = 50001; struct PPoint{//结构体尽量不要定义成Point这种,easy和C/C++本身中的变量同名 double x; double y; PPoint(double _x = 0,double _y = 0):x(_x),y(_y){ } PPoint operator - (const PPoint& op2) const{ return PPoint(x - op2.x,y - op2.y); } double operator^(const PPoint &op2)const{ return x*op2.y - y*op2.x; } }; inline int sign(const double &x){ if(x > epsi){ return 1; } if(x < -epsi){ return -1; } return 0; } inline double sqr(const double &x){ return x*x; } inline double mul(const PPoint& p0,const PPoint& p1,const PPoint& p2){ return (p1 - p0)^(p2 - p0); } inline double dis2(const PPoint &p0,const PPoint &p1){ return sqr(p0.x - p1.x) + sqr(p0.y - p1.y); } inline double dis(const PPoint& p0,const PPoint& p1){ return sqrt(dis2(p0,p1)); } int n; PPoint p[maxn]; PPoint convex_hull_p0; inline bool convex_hull_cmp(const PPoint& a,const PPoint& b){ return sign(mul(convex_hull_p0,a,b)>0)|| (sign(mul(convex_hull_p0,a,b)) == 0 && dis2(convex_hull_p0,a) < dis2(convex_hull_p0,b)); } int convex_hull(PPoint* a,int n,PPoint* b){ int i; for(i = 1 ; i < n ; ++i){ if(sign(a[i].x - a[0].x) < 0 || (sign(a[i].x - a[0].x) == 0 && sign(a[i].y - a[0].y) < 0)){ swap(a[i],a[0]); } } convex_hull_p0 = a[0];//这两行代码不要顺序调换了..否则会WA sort(a,a+n,convex_hull_cmp); b[0] = a[0]; b[1] = a[1]; int newn = 2; for(i = 2 ; i < n ; ++i){ while(newn > 1 && sign(mul(b[newn-1],b[newn-2],a[i])) >= 0){ newn--; } b[newn++] = a[i]; } return newn; } /** * 有一个三角形的三个点来计算这个三角形的面积 */ double crossProd(PPoint A, PPoint B, PPoint C) { return (B.x-A.x)*(C.y-A.y) - (B.y-A.y)*(C.x-A.x); } int main(){ while(scanf("%d",&n)!=EOF){ int i; for(i = 0 ; i < n ; ++i){ scanf("%lf %lf",&p[i].x,&p[i].y); } n = convex_hull(p,n,p); p[n] = p[0]; double max_ans = -1; int j; int k; for(i = 0 ; i < n ; ++i){ for(j = i+1 ; j < n ; ++j){ for(k = j+1 ; k <= n ; ++k){ double ans = fabs(crossProd(p[i],p[j],p[k]))/2; if(max_ans < ans){ max_ans = ans; } } } } printf("%.2lf ",max_ans); } return 0; }






  • 相关阅读:
    u盘的超级用法
    文件夹访问被拒绝
    web移动前端的click点透问题
    call()apply()ind()备忘录
    Safari中的new Date()格式化坑
    dataURI V.S. CSS Sprites 移动端
    css3属性之 box-sizing
    多人协作代码--公共库的引用与业务约定
    web前端本地测试方法
    依赖包拼合方法
  • 原文地址:https://www.cnblogs.com/yfceshi/p/7064288.html
Copyright © 2011-2022 走看看