这系列文章主要记录遇到的一些比较经典的算法题目,不断更新。算法
一、二分算法求多边形外接圆的最大半径。数组
题目要求: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 }