2021牛客寒假算法基础集训营1 E.三棱锥之刻

279 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 3 天,点击查看活动详情

E.三棱锥之刻

P为正三棱锥内部的中心,PA,PD为正三棱锥外接球半径,OP为正三棱锥内切球半径

结论:已知正三棱锥的棱长为a,那么正三棱锥外接球半径为:64a\frac{\sqrt{6}}{4}a ,正三棱锥内切球半径为:612a\frac{\sqrt{6}}{12}a

//minn为正三棱锥内切球半径,maxx为正三棱锥外接球半径
double minn = sqrt(6.0) * a / 12, maxx = sqrt(6.0) * a / 4;
double area;

本题分三种情况:

  1. 当染色半径 r612ar ≤ \frac{\sqrt{6}}{12}a时, 即染色球还未触及正三棱锥内壁,那么就无法染色
if (r <= minn) area = 0;//无法染色,染色面积自然为0
  1. 当染色半径 r64ar ≥ \frac{\sqrt{6}}{4}a时, 即染色球已经包含整个正三棱锥,那么整个正三棱柱的内部都会染色
else if (r >= maxx) area = sqrt(3.0) / 4 * f(a);//正三棱锥一个侧面三角形的面积
  1. 当染色半径 612ar64a\frac{\sqrt{6}}{12}a ≤ r ≤ \frac{\sqrt{6}}{4}a 时,分为两个小情况: (1) 当横截面积 ≤ 是三角形的内切圆 即 横截圆的半径 ≤ 36a\frac{\sqrt{3}}{6}a

此时OG为底面三角形ABC的内切圆,OG为内切圆的半径为:d=36ad = \frac{\sqrt{3}}{6}a ,染色圆的半径为:r

那么染色球与其中一个底面三角形ABC形成的横截圆的半径为:r1=(r612a)2d2r_1 = \sqrt{(r - \frac{\sqrt{6}}{12}a)^2 - d^2}

所以:此时底面三角形ABC染色面积为:πr12πr_1^2 ,有4个面就是 4πr124πr_1^2

(2) 当 正三角形的内切圆 < 横截圆 < 正三角形的外接圆 即 染色的面积如蓝色阴影部分:

这个面积分为两个部分:等腰三角形+扇形

此时的 r1,d,2dr_1, d, 2d 如图所示

3个等腰三角形面积 = r12d2×d×3\sqrt{r_1^2-d^2} × d × 3

扇形的弧度:α=(2πacos(dr1)×2×3)÷3α = (2π - acos(\frac{d}{r_1} )× 2 × 3) ÷ 3

3个扇形面积 = α2π×π×r12×3\frac{α}{2π} × π × r_1^2 × 3

else {
	if (r1 <= d) {
		area = PI * r1 * r1;
	} else {
		double area1 = sqrt(f(r1) - f(d)) * d * 3;/
		double area2 = ((((PI * 2) - (acos(d / r1) * 2) * 3) / 3) / (PI * 2)) * PI * f(r1);
		area = area1 + area2; 
	}
}

本题分三种情况:

  1. 当染色半径 r <= sqrt(6) * a / 12; 那么就无法染色

  2. 当染色半径 r >= sqrt(6) * a / 4; 那么整个正三棱柱的内部都会染色

  3. 当染色半径 sqrt(6) * a / 12 < r < sqrt(6) * a / 4 时分为两个小情况:

    (1)当横截面积 恰好是三角形的内切圆

    (2)当横截面积 大于正三角形的内切圆 小于正三角形的外接圆

完整的AC代码:

#include<bits/stdc++.h>
#define ll long long
#define int ll
#define PI acos(-1)
#define MOD 1000000007
using namespace std;
//x的平方
double f(double x) {
    return x * x;
}
signed main() {
    double a;//题目给的正三棱锥的棱长
    double r;//题目给的染色的半径
    scanf("%lf%lf", &a, &r);
    // sqrt(6) * a / 12;是正三棱柱内切球的半径
    // sqrt(6) * a / 4; 是正三棱柱外接球的半径
    double minn = sqrt(6.0) * a / 12, maxx = sqrt(6.0) * a / 4;
    double r1 = sqrt(f(r) - f(sqrt(6.0) * a / 12));//在正三棱锥的一个侧面被染色截面圆的半径
    double d = sqrt(3.0) / 6 * a;//正三角形的内切圆的半径
     
    double area;
    if (r <= minn) area = 0;
    else if (r >= maxx) area = sqrt(3.0) / 4 * f(a);//正三棱锥一个侧面三角形的面积
    else {
        if (r1 <= d) {
            area = PI * r1 * r1;
        } else {
            double area1 = sqrt(f(r1) - f(d)) * d * 3;//3个等腰三角形的面积
            //cos() 是已知一个角的弧度值 x,求该角的余弦值 y;而 acos() 是已知一个角的余弦值 y,求该角的弧度值 x。
            double area2 = 3 * ((((PI * 2) - (acos(d / r1) * 2) * 3) / 3) / (PI * 2)) * PI * f(r1);//扇形面积 = ((2 * PI - 三个等腰三角形的角度) * 3 / 3) / PI * 2 * PI * f(r1);
            area = area1 + area2;
        }
    }
    printf("%.6lf\n", area * 4);
    return 0;
}