分析

分情况讨论

  1. 中心到底面的距离 >= r, 答案为0。
  2. 中心到底面的距离 < r <= 中心到棱的中点的距离, 重叠的部分是圆。
  3. 棱的中点的距离 < r <= 中心到棱的顶点的距离,圆有一部分超过了三角形,计算超出的弧长,用的圆面积减去超过的,再乘以每个面。中间要算角度比较麻烦。
  4. 中心到棱的顶点的距离 <= r, 全部表面积。

全视图

图片说明

底面(情况3)

这张图片由 @KirbyOvO 大佬提供。

图片说明

#include<bits/stdc++.h>

using namespace std;

typedef long long LL;
typedef pair<int,int> PII;

#define x first
#define y second

const int N = 2e8, mod = 1e9 + 7;
const double PI = 3.1415926;

void solve()
{
    double a, r;
    cin >> a >> r;
    double rmax = a * sqrt(6) / 4.0;
    double rmin = sqrt(2) * a / 4.0;
    double t = sqrt(6) * a / 3 - rmax; // O2O3
    if(r <= t) cout << "0.000" << endl;
    else if(r <= rmin)
    {
        double ans = PI * (r * r - t * t) * 4;
        printf("%f\n", ans);
    }
    else if(r <= rmax)
    {
        double d = (r * r - t * t); // 斜边和半径
        double b = (d - a * a / 12) * 4; // 底边
        double cs = (d + d - b) / (2 * d); // cosx
        double tri = a / sqrt(12) * sqrt(b) / 2;
        double ans = (PI * d - 3 * (acos(cs) / 2 * d - tri)) * 4;
        printf("%f\n", ans);
    }
    else
    {
        double ans = a * sqrt(3) * a;
        printf("%f\n", ans);
    }
}

int main()
{
    /*ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int t;
    cin >> t;
    while(t --)*/
        solve();
}