K. Keyboard Free 题解

Keyboard Free

https://ac.nowcoder.com/acm/contest/5667/K

固定点 ,枚举点 ,计算 点到直线 的期望高度。

求期望高度

如上图, 为第一个动点, 为第二个点,通过 可以算出线段 的长度,进而得到 ()。此时,可以丢弃这个斜着的图形,只保留该角度 放正图形容易进行积分,得到期望高度为

由于做了两次积分,两个随机变量都服从 的均匀分布,需要除两次

代码

#include <iostream>
#include <cstdio>
#include <cassert>
#include <cstring>
#include <cmath>
#include <functional>
#include <algorithm>
#include <utility>
#include <vector>
#include <string>
#define ms(a,b) memset(a,b,sizeof(a))
using namespace std;
using ll = long long;
using PII = pair<int,int>;
const int mod = 998244353;
const int inf = 1 << 30;
const int maxn = 200000 + 5;

const int Turn = 500;
const double pi = acos(-1.0);
const double eps = 1e-8;

inline double sqr(double x) { return x * x; }

int r1, r2, r3;
double Sin[Turn + 5], Cos[Turn + 5];

int main() {
  for (int i = 0; i <= Turn; i++) {
    Sin[i] = sin(2.0 * i * pi / Turn);
    Cos[i] = cos(2.0 * i * pi / Turn);
  }
  int T; scanf("%d", &T);
  while (T--) {
    scanf("%d%d%d", &r1, &r2, &r3);

    if (r1 > r2) swap(r1, r2);
    if (r2 > r3) swap(r2, r3);
    if (r1 > r2) swap(r1, r2);
    assert(r1 <= r2 && r2 <= r3);

    double ans = 0;
    for (int i = 0; i < Turn; i++) {
      double X = r2 * Cos[i], Y = r2 * Sin[i];
      double L = sqrt(sqr(X - r1) + sqr(Y));
      if (L < eps) continue;
      double H = r1 * Y / L;
      if (H >= r3) {
        ans += H * L / 2.0;
      } else {
        double alpha = asin(H / r3);
        double E = 2.0 * (H * alpha + sqrt(sqr(r3) - sqr(H)));
        ans += E * L;
      }
    }
    ans /= 2 * pi * Turn;
    printf("%.1lf\n", ans);
  }
  return 0;
}
全部评论

相关推荐

11-09 12:17
清华大学 C++
out11Man:小丑罢了,不用理会
点赞 评论 收藏
分享
12-12 10:59
门头沟学院 C++
点赞 评论 收藏
分享
评论
6
收藏
分享
牛客网
牛客企业服务