问题1:分割木棒
算法
二分法
Code
问题2:凸多边形
#include<cstdio>
#include<cmath>
const double PI = acos(-1.0);
const double eps = 1e-5; //比较精度
//求圆心角之和
double totalCornerAngles(double edges[],int n,doule r){
double sum = 0.0;
for(int i = 0;i<n;++i){
sum += asin(edges[i]/2/r)*2;
}
return sum;
}
int main(){
int N;//边数
scanf("%d",&N); //输入边数
double edges[N]; //边长数组
double sum;//圆心角之和
double maxAngle = 0.0;//最长边对应的圆心角
double maxEdge = 0.0;//最长边
//初始化edges
for(int i = 0;i<N;++i){
scanf("%lf",&edges[i]);
if(edges[i]>maxEdge){
maxEdge = edges[i];
}
}
//以最长边为直径求圆心角之和,若为2Π则直接返回
sum = totalCornerAngles(edges,N,maxEdge/2);
if(fabs(sum-PI*2)<eps){
printf("外接圆的最大半径是最大边的一半:%.2f",maxEdge/2);
return 0;
}
//半径大于最大边的一半(即斜边大于直角边)
double left = maxEdge/2,right = 10000000,mid;
double other = 0;
//在误差范围内循环求解
while(right-left>eps){
mid = (right+left)/2;//半径
maxAngle = asin(maxEdge/2/mid)*2; //求出最大边对应的圆心角
sum = totalCornerAngles(edges,N,mid);
other = sum - maxAngle;
//如果除去最大圆心角的其他圆心角之和小于Π,说明圆心在多边形外面
if(other<PI){
sum = other + 2*PI - maxAngle;
if(sum<2*PI){
left = mid;
}else{
right = mid;
}
}else{//圆心在多边形里面
if(sum>2*PI){
left = mid;
}else{
right = mid;
}
}
}
printf("外接圆的最大半径是: %.2f",mid);
return 0;
}