1. 程式人生 > >hdu step 7 1 6 最大三角形 凸包的應用——在n個點中找到3個點 它們所形成的三角形面積最大

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
33 42 63 762 63 92 08 06 67 7
Sample Output
1.5027.00
AuthorEddy
Recommendlcy

題目分析:

             凸包的簡單應用,在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這種,容易和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 = 2for(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\n",max_ans); } return 0;}