zoukankan      html  css  js  c++  java
  • 比赛

    Description

    有两个队伍A和B,每个队伍都有n个人。这两支队伍之间进行n场1对1比赛,每一场都是由A中的一个选手与B中的一个选手对抗。同一个人不会参加多场比赛,每个人的对手都是随机而等概率的。例如A队有A1和A2两个人,B队有B1和B2两个人,那么(A1 vs B1,A2 vs B2)和(A1 vs B2,A2 vs B1)的概率都是均等的50%。

    每个选手都有一个非负的实力值。如果实力值为X和Y的选手对抗,那么实力值较强的选手所在的队伍将会获得(X-Y)^2的得分。

    求A的得分减B的得分的期望值。

    Input
    第一行一个数n表示两队的人数为n。
    第二行n个数,第i个数A[i]表示队伍A的第i个人的实力值。
    第三行n个数,第i个数B[i]表示队伍B的第i个人的实力值。

    Output
    输出仅包含一个实数表示A期望赢B多少分。答案保留到小数点后一位(注意精度)。

    Sample Input
    2
    3 7
    1 5

    Sample Output
    20.0

    Data Constraint

    Hint
    对于30%的数据,n≤50。
    对于100%的.据,n≤50000;A[i],B[i]≤50000。
    .
    .
    .
    .
    .
    .

    分析

    我们首先要搞懂这里的期望是指什么,指n场比赛后总得分的平均数(平均数是所有可能的总得分情况的平均数)
    然后这个要自己体会体会
    接着讲怎么做这题
    我们拿一个我自造的数据说吧:
    3
    3 7 5
    1 5 6
    只拿3来说,它的期望是-9,怎么算的呢?这样:
    (3-1)^2-(3-5)^2-(3-6)^2
    注:中间的连接符号应默认为加号,但是因为bi比3大,所以变为减号
    但是这样不就是n^2的算法吗,怎么做啊?
    把上面的式子展开:
    3^2-2*3*1+1^2-(3^2-2*3*5+5^2)-(3^2-2*3*6+6^2)
    然后我们合并同类项:
    -2*3^2-2*3*(-1+5+6)+(1^2-5^2-6^2)
    我们先把b队赢了x分就等同于a队输了x分这个思想丢掉,上述式子可以表述为:
    n*ai^2+2*ai*∑bi+∑bi^2
    但我们发现并非如此,因为ai不一定能赢对面所有人,所以我设了四个变量:
    s,表示∑bi中负数的部分
    v,表示∑bi中正数的部分
    f,表示∑bi^2中应为负数的部分
    w,表示∑bi^2中应为正数的部分
    然后我们给a,b从小到大排序
    然后i循环中套一个j循环
    用一个k记录最小的大过ai的数的位置,然后每次j从那里开始,也更新k值
    如果当前枚举到的ai大过bk了,那么就要在s,f中减去bk所占的数,在v,w中加上bk所占的数,然后一直找到最小的超过ai的数
    对就是这样
    然后最后因为是n场的期望嘛,要变成每一场的平均期望那就要除n咯
    温馨提示:请使用2^63-1运算,最后不要忘记转小数哦
    .
    .
    .
    .
    .
    .

    程序:
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    int n,i,j,k,l;
    long long a[50001],b[50001];
    long long ans,s,v,f,w;
    int main()
    {
        cin>>n;
        for (int i=1;i<=n;i++)
        cin>>a[i];
        for (int i=1;i<=n;i++)
        {
            cin>>b[i];
            s=s+b[i];
            f=f+b[i]*b[i];
        }
        sort(a+1,a+n+1);
        sort(b+1,b+n+1);
        k=1;
        for (int i=1;i<=n;i++)
        {
            for (j=k;j<=n;j++)
            if (a[i]>=b[j])
            {
                v=v+b[j];
                s=s-b[j];
                w=w+b[j]*b[j];
                f=f-b[j]*b[j];
            }
            else break;
            k=j;
            ans=ans+(2*(k-1)-n)*a[i]*a[i]-2*a[i]*(v-s)+w-f;
        }
        printf("%.1lf",(double)ans/n);
    }
  • 相关阅读:
    Mybatis动态数据源
    [Java基础]判断字符串指定字符类型
    [Java基础]让Map value自增
    (转载)UTF-8占几个字符
    JVM程序计数器
    Mybatis异常总结
    通过类对象来获取类中的属性,方法,构造器
    主动引用和被动引用
    ClassLoader类加载器浅见
    反射----获取class对象的五种方法
  • 原文地址:https://www.cnblogs.com/YYC-0304/p/9499962.html
Copyright © 2011-2022 走看看