点击查看代码
#include<cstdio>
#include<cmath>
#pragma warning(disable:4996)
const double PI = acos(-1.0);
const double eps = 1e-5;//比较精度
//求圆心角之和
double totalCornerAngles(double edges[], int n, double r){
double sum = 0.0;
for (int i = 0; i < n; i++) {
sum += asin(edges[i] / 2 / r) * 2;
}
return sum;
}
//二分法求半径
int main(){
double edges[10];//存储每条边长度,最多10条边
int N;//边数
scanf("%d", &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];//保存最长边
}
//以最长边为直径求圆心角之和,若为2pi则直接返回
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;
//如果除去最大圆心角的其他圆心角之和小于pi,说明圆心在多边形外面
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;
}