• 牛客多校赛2K Keyboard Free


    Description

    给定 (3) 个同心圆,半径分别为 (r1,r2,r3) ,三个点分别随机分布在三个圆上,求这个三角形期望下的面积。

    Solution

    首先可以固定 (A) 点,枚举 (B) 点。
    对于一个固定的 (AB) ,我们可以求出线段长度 (L) 以及它与圆心的距离 (H) 和夹角 (alpha) ,显然有 (alpha < frac{pi}{2})
    接着通过积分求出 (C) 点运动时这个三角形的期望高,我们将其分成三部分。
    第一部分:

    [sum=int_{0}^{pi}(H+r3 imes sin(x))dx=pi H + r3 imes int_{0}^{pi}sin(x)dx=pi H+2 imes r3 ]

    第二部分:

    [sum=2int_{0}^{alpha}(H-r3 imes sin(x))dx=2(Halpha - r3int_{0}^{alpha}sin(x)dx)=2(alpha H +r3 imes cos(alpha)-r3) ]

    第三部分:

    [sum=int_{alpha}^{pi-alpha}(r3 imes sin(x)-H)dx=r3int_{alpha}^{pi-alpha}sin(x)dx-(pi-2alpha)H=2r3 imes cos(alpha)-(pi-2alpha)H ]

    合并在一起,得:

    [sum=pi H+2 imes r3+2(alpha H +r3 imes cos(alpha)-r3)+2r3 imes cos(alpha)-(pi-2alpha)H=4r3 imes cos(alpha)+4alpha imes H ]

    所以,期望高度为 (h=frac{4r3 imes cos(alpha)+4alpha imes H}{2pi}) ,故期望三角形面积为 (frac{h imes L}{2})
    我们可以在圆周上均匀选取 (1000)(B) ,这样做答案近似度极高,如只保留一位小数精度足矣。
    时间复杂度:(O(1000T))

    Code

    提交记录

    // Author: wlzhouzhuan
    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #include <bits/stdc++.h>
    using namespace std;
    
    #define ll long long
    #define ull unsigned long long
    #define rint register int
    #define rep(i, l, r) for (rint i = l; i <= r; i++)
    #define per(i, l, r) for (rint i = l; i >= r; i--)
    #define mset(s, _) memset(s, _, sizeof(s))
    #define pb push_back
    #define pii pair <int, int>
    #define mp(a, b) make_pair(a, b)
    #define debug(x) cerr << #x << " = " << x << '
    ';
    #define pll pair <ll, ll>
    
    inline int read() {
      int x = 0, neg = 1; char op = getchar();
      while (!isdigit(op)) { if (op == '-') neg = -1; op = getchar(); }
      while (isdigit(op)) { x = 10 * x + op - '0'; op = getchar(); }
      return neg * x;
    }
    inline void print(int x) {
      if (x < 0) { putchar('-'); x = -x; }
      if (x >= 10) print(x / 10);
      putchar(x % 10 + '0');
    }
    
    const double eps = 1e-8;
    const double PI = acos(-1.0);
    
    double Sin[1005], Cos[1005];
    double r1, r2, r3;
    
    double sqr(double x) { return x * x; }
    void solve() {
      cin >> r1 >> r2 >> r3;
      if (r1 > r2) swap(r1, r2);
      if (r1 > r2) swap(r1, r3);
      if (r2 > r3) swap(r2, r3);
      double ans = 0.0;
      for (int i = 1; i <= 1000; i++) {
        // B 坐标 
        double X = r2 * Cos[i], Y = r2 * Sin[i];
        double L = sqrt(sqr(X - r1) + sqr(Y));
        double H = Y / L * r1;
        double alpha = asin(H / r3);
        double h = (4.0 * r3 * cos(alpha) + 4.0 * alpha * H) / (2.0 * PI);
        ans += h * L / 2.0;
      }   
      ans /= 1000.0;
      cout << fixed << setprecision(1) << ans << '
    ';
    }
    
    int main() {
      ios::sync_with_stdio(false), cin.tie(0);
      int T;
      cin >> T;
      for (int i = 1; i <= 1000; i++) {
        Sin[i] = sin(2.0 * PI / 1000.0 * i);
        Cos[i] = cos(2.0 * PI / 1000.0 * i);
      }
      while (T--) solve();
      return 0; 
    }
    
  • 相关阅读:
    docker入门(一)
    netstat命令
    grep的小技巧
    gd库的安装
    jar命令的用法详解
    关于awk的范围模式功能问题
    更换文本中第二次出现的字符串内容
    awk打印第n个参数到最后一个技巧/将n行组成一列
    awk -f program.file 功能使用
    shell的变量处理
  • 原文地址:https://www.cnblogs.com/wlzhouzhuan/p/13301358.html
Copyright © 2020-2023  润新知