這系列文章主要記錄遇到的一些比較經典的算法題目,不斷更新。算法
一、二分算法求多邊形外接圓的最大半徑。數組
題目要求:spa
給出N個線段長度,試將它們頭尾相接組合成一個凸多邊形,使凸多邊形的外接圓(多邊形每一個頂點都在圓上)的半徑最大,求該最大半徑。其中N<=10^5,線段長度均不超過100,要求算法中不涉及座標的計算。code
思路:blog
二分算法的的本質就是經過不斷迭代使left 和 right 在固定條件下逐漸靠近真實值,符合必定偏差,本題能夠固定條件取爲:凸多邊形的外接圓的弧度爲2π
get
1 #include<stdio.h> 2 3 /** 4 * 求弧度 5 **/ 6 7 double getTotalRadian(double edges[],int n,double r) 8 { 9 double radian = 0.0,asinValue; 10 for(int i =0;i<n;i++) 11 radian+=asin(edges[i]/2/r)*2; 12 return radian; 13 } 14 15 16 /** 17 * 二分查找求最大半徑 18 */ 19 void maxR() 20 { 21 //錯誤率 22 double error = 1e-5,p; 23 //邊的個數 24 int n; 25 //邊長數組 26 double edges[5000]; 27 //弧度 最大邊 π 28 double radian, maxEdge=0.0, pi = 3.1415926535 ; 29 30 //初始化edges 31 scanf("%d",&n); 32 for(int i=0;i<n;i++) 33 { 34 scanf("%lf",&edges[i]); 35 if(edges[i]>maxEdge) 36 maxEdge = edges[i]; 37 } 38 39 //若最長邊爲直徑,則直接處理 40 radian = getTotalRadian(edges,n,maxEdge/2); 41 if(abs(radian-pi*2)<error) 42 { 43 printf("外接圓的最大半徑是:%.2f",maxEdge/2); 44 return ; 45 } 46 47 //左 中 右 48 double left =0,right=10000000,mid; 49 //在偏差範圍內循環求解 50 while(right -left >error) 51 { 52 mid = (right + left) /2; 53 radian = getTotalRadian(edges,n,mid); 54 if( radian > 2*pi) 55 left = mid; 56 else 57 right = mid; 58 } 59 printf("外接圓的最大半徑是:%.2f",mid); 60 61 }