99.9%的人不会做的结论题
2024-12-21 20:56:55
发布于:上海
见:https://www.acgo.cn/problemset/info/33690
题解
引理一 必存在一圆外接于一个边长固定的多边形
显然
引理二 正四边形的面积最大值当且仅当其内接于一个圆时取到
考虑多边形 , 其边长为 , 对 和 分别使用余弦定理,可得:
又由正弦定理,可得 ,从而:
整理即得:
显然,确定时,若要 最大,则必有 ,即 ,所以 四点共圆。
引理三 圆内接多边形的面积大小与其各边排列无关
考虑圆内接多边形 和其外接圆 , 记其半径为 , 各边边长为 , 过 作 , 根据垂径定理,都是半径且分别平分 ,因此:
所以内接于同一个圆的,各边边长组成的有序 元组等价的多边形面积相等。接下来证明 排列各边必内接于 , 令多边形 的圆心角分别为 现将多边形各边重新排列,其各边所对圆心角变为 , 由于 本质上是 的一个排列,因此:
同时易得变换后的多边形 的各点依旧在 上,因此多边形 依旧内接 .
引理四 边长固定的多边形在其内接于一圆时面积取得最大值
充分性:
考虑多边形 的相邻四个顶点 (规定 为正整数且 等价于 )。若 不共圆,则必定可以找到一个四边形 使得其各个边的边长和四边形 的相等,根据引理二,有 。同时若将四边形 替换为四边形 。可使多边形 剩余部分形状不变。因此要使 的面积最大,其任意相邻的四个顶点共圆,因此 内接于一圆。
必要性:
若内接于圆的多边形 面积并未达到最大,则考虑将 以及 进行形变,使得(单个边或弓形的形状不变)使得其其面积更大,此时:
然而整个图形的边长并未改变,面积却增加了,与等周定理矛盾,因此内接于圆的多边形 面积必定达到最大。同理,面积最大的 唯一。
解答
根据引理四,所求多边形 必内接于一圆,记其各边边长为 ,外接圆半径为 ,各边所对应圆心角为 。注意到:
再由欧拉公式变形:
的等式两边同取指数,得:
因此可得 满足方程:
求出 的解析解后,根据引理三可得 的值。
展示结果的代码(注意直接提交该代码不能通过该题,因为开了O2,请使用Dev编译运行)
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3, "Ofast", "inline")
#include<bits/stdc++.h>
using namespace std;
const int prec0 = 500000;//表示精度,值越大,精度越高,运行时间越长。
const double inf = 100000000;
int a[10];
double r1 = 0;
int maxnum = -1, sum = 0, n = 0;
struct complex_number{
double real_part;
double imaginary_part;
}result;
double get_root(double x, int prec){//C++开大整数根号的精度堪忧,此处写牛顿迭代开根号备用,prec表示精度
if(x <= 1) return sqrt(x);
int r = x;
vector <double> table;
table.push_back(1);
for(int i = 1; i <= prec; i++){
table.push_back((1.0 / 2.0) * (table[i - 1] + r / table[i - 1]));
}
return table[prec];
}
double quick_pow(double x, int power){//快速幂算法
double result = 1;
while(power){
if(power & 1)
result = result * x;
x = x * x;
power >>= 1;
}
return result;
}
double find_value(double x){//计算r = x时(10)式等式左侧减去1的值的实部
result.imaginary_part = 0;
result.real_part = 0;
if(2 * x < maxnum * 1.0) return 0 - inf;
complex_number num;
for(int i = 1; i <= n; i++){
if(i == 1){
result.imaginary_part = (a[i] * 1.0) / (2.0 * x);
result.real_part = sqrt(1.0 - quick_pow((a[i] * 1.0) / (2.0 * x), 2));
}else{
num.imaginary_part = (a[i] * 1.0) / (2.0 * x);
num.real_part = sqrt(1.0 - quick_pow((a[i] * 1.0) / (2.0 * x), 2));
double p0 = result.real_part * num.real_part - result.imaginary_part * num.imaginary_part;
double q0 = result.real_part * num.imaginary_part + result.imaginary_part * num.real_part;
result.real_part = p0;
result.imaginary_part = q0;
}
}
return result.real_part;
}
double find_radius(){
double ans = 0;
double mininum = inf;
for(int i = maxnum / 2; i <= sum * prec0; i++){
if(fabs(find_value((i * 1.0) / prec0) + 1) < mininum){
mininum = fabs(find_value((i * 1.0) / prec0) + 1);
ans = (i * 1.0) / prec0;
}
}
return ans;
}
void print_ans(){
double value = 0;
for(int i = 1; i <= n; i++){
value += a[i] * sqrt(quick_pow(r1, 2) - 0.25 * quick_pow(a[i], 2));
}
value /= 2;
cout << "The maximum area is : ";
printf("%.15f", value);
cout << endl << "The radius of the circumcircle is : ";
printf("%.7f", r1);
}
int main(){
//输入为 5 2 2 2 3 3,精确答案为9.6824,r1 = 2.0656
scanf("%d", &n);
for(int i = 1; i <= n; i++){
scanf("%d", &a[i]);
maxnum = max(maxnum, a[i]);
sum += a[i];
}double flag = sum / 2;
for(int i = 1; i <= n ;i++){
if(a[i] > flag){
cout << "doesn't exsist";
return 0;
}
}
r1 = find_radius();
print_ans();
return 0;
}
如果你看到一篇在其他平台上但内容大致相同的文章,不要怀疑是我抄袭,因为那篇也是我写的。
全部评论 4
顶
2024-12-21 来自 上海
1古希腊掌管题解版书的神
2024-12-21 来自 湖南
0强强强
2024-12-21 来自 广东
0看不懂一点
2024-12-21 来自 广东
0我去逆天
2024-12-24 来自 广东
0
2024-12-07 来自 广东
0
有帮助,赞一个