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; }






  • 相关阅读:
    HDU 1501 Zipper(DFS)
    HDU 2181 哈密顿绕行世界问题(DFS)
    HDU 1254 推箱子(BFS)
    HDU 1045 Fire Net (DFS)
    HDU 2212 DFS
    HDU 1241Oil Deposits (DFS)
    HDU 1312 Red and Black (DFS)
    HDU 1010 Tempter of the Bone(DFS+奇偶剪枝)
    HDU 1022 Train Problem I(栈)
    HDU 1008 u Calculate e
  • 原文地址:https://www.cnblogs.com/yfceshi/p/7064288.html
Copyright © 2011-2022 走看看