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;
}
posted @ 2020-06-01 17:33  GsjzTle  阅读(232)  评论(0编辑  收藏  举报