一、题目
1、题目描述
2、输入输出
2.1输入
2.2输出
3、原题链接
1157D - N Problems During K Days |
二、解题报告
1、思路分析
考虑总的前两场赢第三场输方案数:((n - 1) * n / 2) ^ 3
如何在较好时间复杂度内求解 前两场赢第三场输 且总分低于对方的方案?
我们只需枚举第三场的分差x,那么前两场分差小于x的方案和第三场分差为x的方案相乘
考虑先O(N^2)计算所有分差的数目,然后O(M^2)计算前两场分差为x1 + x2的数目
然后利用前缀和求解即可
2、复杂度
时间复杂度: O(N^2 + U^2),U = 5000 空间复杂度:O(N + U)
3、代码详解
#include <bits/stdc++.h>
// #define DEBUG
using i64 = long long;
using u32 = unsigned;
using u64 = unsigned long long;
void solve() {
int n;
std::cin >> n;
std::vector<int> a(n);
for (int i = 0; i < n; ++ i) std::cin >> a[i];
std::vector<int> cnt(5000);
for (int i = 0; i < n; ++ i)
for (int j = 0; j < i; ++ j)
++ cnt[abs(a[i] - a[j])];
std::vector<i64> acc(5000);
for (int i = 0; i < 5000; ++ i)
for (int j = 0; j + i < 5000; ++ j)
acc[i + j] += cnt[i] * cnt[j];
for (int i = 1; i < 5000; ++ i)
acc[i] += acc[i - 1];
i64 tot = 0;
for (int i = 0; i < 4999; ++ i)
tot += acc[i] * cnt[i + 1];
std::cout << std::setprecision(12) << 1.0 * tot / pow(1.0 * (n - 1) * n / 2, 3);
}
auto init_ = []{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
return 0;
} ();
int main() {
#ifdef DEBUG
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
int t = 1;
// std::cin >> t;
while (t --)
solve();
return 0;
}