程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> poj 3831 Open-air shopping malls

poj 3831 Open-air shopping malls

編輯:C++入門知識

題目:給定n個圓,需要在某個圓的圓心做一個大圓,使得大圓至少所有給定的一半面積,求出大圓的最小半徑。   分析:計算幾何、二分。此題本質是求解圓的相交面積。直接利用相交面積求解比較困難,而且會出現精度問題。由於規模較小,所以直接枚舉圓心,二分半徑求解。對於圓相交面積的求法:方法1.利用圓的方程聯立二元二次方程組,求解交點,求解交點間距離,利用余弦定理和海倫公式,求解出兩個拱形面積加和;精度會出現問題,而且會出現數據溢出。方法2:求出圓心距離,利用菱形面積和正弦定理列出面積等式,求解交點間距離,然後利用余弦定理求出兩扇形面積減去菱形面積;計算次數較多,精度會出現問題。方法3:求出圓心距離,利用余弦定理直接求出兩個扇行面積加和後減去三角形面積即可。這裡使用方法3。   注意:精度控制。   [cpp]   #include <stdio.h>   #include <stdlib.h>   #include <math.h>      typedef struct point   {       double x,y;   }point;   point  P[ 25 ];   double r[ 25 ];      double cxcarea( point a, point b, double r1, double r2 )   {       double dc = sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));       double r = r1<r2?r1:r2;       double R = r1>r2?r1:r2;              if ( dc-1e-8 > r+R ) return 0.0;       if ( dc+1e-8 < R-r ) return acos(-1.0)*r*r;              double a1 = acos((r*r+dc*dc-R*R)/(2.0*r*dc));       double a2 = acos((R*R+dc*dc-r*r)/(2.0*R*dc));              return a1*r*r+a2*R*R-dc*r*sin(a1);   }      int cover( int n, double R )   {       for ( int i = 1 ; i <= n ; ++ i ) {           int flag = 1;           for ( int j = 1 ; j <= n ; ++ j ) {               double s1 = cxcarea( P[i], P[j], R, r[j] );               double s2 = acos(-1.0)*r[j]*r[j];               if ( s1*2.0 < s2 ) {                   flag = 0;                   break;               }           }           if ( flag ) return 1;       }       return 0;   }      double b_search( int n )   {       double l = 0.0,r = 50000.0,m;       while ( r-l > 1e-8 ) {           m = (l+r)/2.0;           if ( cover( n, m ) )               r = m;           else l = m;       }       return r;   }      int main()   {       int T,N;       while ( scanf("%d",&T) != EOF )        while ( T -- ) {           scanf("%d",&N);           for ( int i = 1 ; i <= N ; ++ i )               scanf("%lf%lf%lf",&P[i].x,&P[i].y,&r[i]);                      printf("%.4lf\n",b_search(N));       }   }    

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved