Codeforces 626D Jerry's Protest
题目链接
https://codeforces.com/problemset/problem/626/D
题目大意
给你 N 个球,每个球都有自己的分数 ai
现在有两个人 A , B 进行游戏 , 一共三轮 , 每轮每个人从中抽取一个球 , 谁球的分数大谁胜
胜者可以获得abs(两球分值差)的积分
已知 A 赢了两轮 , B 赢了 一轮 ,问 B 获得的积分比 A 大的概率是多少
解题思路
概率 + 思维
对于一场比赛可能出现的情况有 C(n , 2)种 , 那么三场一共就有 C(n , 2) ^ 3种
我们设 one[i] 表示赢一场获得 i 积分情况数 , two[i] 表示赢两场获得 i 积分的情况数
那么它们的求法如下 :
sort(a + 1 , a + 1 + n); for(int i = 1 ; i <= n ; i ++) for(int j = i + 1 ; j <= n ; j ++) one[a[j] - a[i]] ++ ; for(int i = 1 ; i <= 5000 ; i ++) for(int j = 1 ; j <= 5000) two[i + j] += one[i] * one[j];
于是易得 B 获得积分比 A 多的情况数计算方式为:
int sum = 0; for(int i = 1 ; i <= 10000 ; i ++) for(int j = i + 1 ; j <= 5000 ; j ++) sum += two[i] * one[j];
那么这题就这样轻松解决了
AC_Coder
#include<bits/stdc++.h> #define rep(i,a,n) for (int i=a;i<=n;i++) #define int long long using namespace std; const int N = 2e5 + 10; int a[N] , one[N] , two[N]; signed main() { int n; cin >> n; int tot = n * (n - 1) >> 1; rep(i , 1 , n) cin >> a[i]; sort(a + 1 , a + 1 + n); rep(i , 1 , n) rep(j , i + 1 , n) one[a[j] - a[i]] ++ ; rep(i , 1 , 5000) rep(j , 1 , 5000) two[i + j] += one[i] * one[j]; int sum = 0; rep(i , 1 , 10000) rep(j , i + 1 , 5000) sum += two[i] * one[j]; double ans = (1.0) * sum / tot / tot / tot; cout << setprecision(10) << fixed << ans << '\n'; return 0; }
凡所不能将我击倒的,都将使我更加强大