经典的算法题目(一)

这系列文章主要记录遇到的一些比较经典的算法题目,不断更新。

1、二分算法求多边形外接圆的最大半径。

题目要求:

  给出N个线段长度,试将它们头尾相接组合成一个凸多边形,使凸多边形的外接圆(多边形每个顶点都在圆上)的半径最大,求该最大半径。其中N<=10^5,线段长度均不超过100,要求算法中不涉及坐标的计算。

思路:

  二分算法的的本质就是通过不断迭代使left 和 right 在固定条件下逐渐靠近真实值,符合一定误差,本题可以固定条件取为:凸多边形的外接圆的弧度为2π

 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 }
原文地址:https://www.cnblogs.com/beiyan/p/8312801.html