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

E.三棱锥之刻

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

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

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

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

本题分三种情况:

  1. 当染色半径 r ≤ 6 12 a r ≤ \frac{\sqrt{6}}{12}a r126 a时, 即染色球还未触及正三棱锥内壁,那么就无法染色
if (r <= minn) area = 0;//无法染色,染色面积自然为0
  1. 当染色半径 r ≥ 6 4 a r ≥ \frac{\sqrt{6}}{4}a r46 a时, 即染色球已经包含整个正三棱锥,那么整个正三棱柱的内部都会染色
else if (r >= maxx) area = sqrt(3.0) / 4 * f(a);//正三棱锥一个侧面三角形的面积
  1. 当染色半径 6 12 a ≤ r ≤ 6 4 a \frac{\sqrt{6}}{12}a ≤ r ≤ \frac{\sqrt{6}}{4}a 126 ar46 a 时,分为两个小情况:
    (1) 当横截面积 ≤ 是三角形的内切圆 即 横截圆的半径 ≤ 3 6 a \frac{\sqrt{3}}{6}a 63 a
    2021牛客寒假算法基础集训营1 E.三棱锥之刻_第2张图片

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

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

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

(2) 当 正三角形的内切圆 < 横截圆 < 正三角形的外接圆 即 染色的面积如蓝色阴影部分:
2021牛客寒假算法基础集训营1 E.三棱锥之刻_第3张图片

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

此时的 r 1 , d , 2 d r_1, d, 2d r1,d,2d 如图所示

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

扇形的弧度: α = ( 2 π − a c o s ( d r 1 ) × 2 × 3 ) ÷ 3 α = (2π - acos(\frac{d}{r_1} )× 2 × 3) ÷ 3 α=(2πacos(r1d)×2×3)÷3

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

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。
			//扇形面积 = ((2 * PI - 三个等腰三角形的角度) * 3 / 3) / (PI * 2) * PI * f(r1);
			double area2 = ((((PI * 2) - (acos(d / r1) * 2) * 3) / 3) / (PI * 2)) * PI * f(r1);
			area = area1 + area2; 
		}
	}

完整的AC代码:

#include
#include
#include
#include
#include
#include
#define ll long long
#define int ll
#define PI acos(-1)
#define MOD 1000000007
using namespace std;
int read()
{
    int w = 1, s = 0;
    char ch = getchar();
    while (ch < '0' || ch>'9') { if (ch == '-') w = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { s = s * 10 + ch - '0';ch = getchar(); }
    return s * w;
}
//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;
    /*
    本题分三种情况:
    Ⅰ. 当染色半径 r <= sqrt(6) * a / 12; 那么就无法染色
    Ⅱ. 当染色半径 r >= sqrt(6) * a / 4;  那么整个正三棱柱的内部都会染色
    Ⅲ. 当染色半径 sqrt(6) * a / 12 < r < sqrt(6) * a / 4 时分为两个小情况:
        (1) 当横截面积 恰好是三角形的内切圆
        (2) 当横截面积 大于正三角形的内切圆 小于正三角形的外接圆
     
      
    */
    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;
}

你可能感兴趣的:(竞赛,题解,牛客OJ,算法,数学,几何学,c++)