September 3rd 模拟赛C T2 比赛 Solution

来源:互联网 发布:淘宝app最新版本下载 编辑:程序博客网 时间:2024/06/07 10:38

空降题目处(外网)
点我点我点我
空降题目处(内网)
点我点我点我

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多少分。答案保留到小数点后一位(注意精度)。

Solution

可理解为A不变,B做全排列来匹配.
但是这样是O(N!)的.与题意不符.
所以,我们可以将B排序,做它的前缀和X与前缀平方和Y.
B中二分k,即BkAi小时,k取最大.
然后就是推公式.
i=1n
A队正分:
((AiB1)2+(AiB2)2++(AiBk1)2+(AiBk)2)(N1)!N
=(Ai2AiB1+B1)+(Ai2AiB2+B2)++(Ai2AiBk1+Bk1)+(Ai2AiBk+Bk)N
=(Aik2AiXj+Yj)N
A队负分:
((AiBk+1)2+(AiBk+2)2++(AiBN1)2+(AiBN)2)(N1)!N
=(Ai2AiBk+1+Bk+1)+(Ai2AiBk+2+Bk+2)++(Ai2AiBN1+BN1)+(Ai2AiBN+BN)N
=(Ai(Nk)2Ai(XNXj)+(YNYj))N
即:
Ans=Ni=1(Aik2AiXj+Yj)(Ai(Nk)2Ai(XNXj)+(YNYj))N
还有神奇的精度问题…
这里写图片描述
这里写图片描述
我都不想说话了…
自己调吧,我帮不了你…
头晕?歇菜了?见Code 滑稽

Code

C++

#include<cstdio>#include<cmath>#include<algorithm>#include<cstring>using namespace std;double ans,x[50001],y[50001],a[50001],b[50001];int n,t,j=1;int bs(int l,int r,double d);int get(int x);int main(){    scanf("%d",&n);    for (int i=1;i<=n;i++)        scanf("%lf",&a[i]);    for (int i=1;i<=n;i++)        scanf("%lf",&b[i]);    sort(b+1,b+n+1);    for (int i=1;i<=n;i++)    {        x[i]=x[i-1]+b[i];        y[i]=y[i-1]+b[i]*b[i];    }    for (int i=1;i<=n;i++)    {        t=get(i);        j=t;        ans+=(a[i]*a[i]*(double)(t)-2*a[i]*x[t]+y[t])*1000/n;        ans-=(a[i]*a[i]*(double)(n-t)-2*a[i]*(x[n]-x[t])+(y[n]-y[t]))*1000/n;    }    printf("%.1lf",ans/1000);}int bs(int l,int r,double d){    if (l>=r)        return l;    int m=(l+r)/2;    if (d<b[m+1])        return bs(l,m,d);    else        return bs(m+1,r,d);}int get(int x){    int value=0;    int l=1,r=n,mid;    while (l<=r)    {        mid=(l+r)/2;        if (b[mid]>a[x]) r=mid-1;        else {l=mid+1;value=mid;}    }    return(value);}

Pascal

var        a,b,sq,pre:array[0..50000] of int64;        i,j,n:longint;        score_a,score_b:int64;procedure qsort_a(l,r:longint);var        i,j,mid:longint;begin        i:=l;        j:=r;        mid:=a[(i+j) div 2];        repeat                while a[i]<mid do inc(i);                while a[j]>mid do dec(j);                if i<=j then                begin                        a[0]:=a[i];                        a[i]:=a[j];                        a[j]:=a[0];                        inc(i);                        dec(j);                end;        until i>j;        if l<j then qsort_a(l,j);        if i<r then qsort_a(i,r);end;procedure qsort_b(l,r:longint);var        i,j,mid:longint;begin        i:=l;        j:=r;        mid:=b[(i+j) div 2];        repeat                while b[i]<mid do inc(i);                while b[j]>mid do dec(j);                if i<=j then                begin                        b[0]:=b[i];                        b[i]:=b[j];                        b[j]:=b[0];                        inc(i);                        dec(j);                end;        until i>j;        if l<j then qsort_b(l,j);        if i<r then qsort_b(i,r);end;begin        readln(n);        for i:=1 to n do read(a[i]);        for i:=1 to n do read(b[i]);        qsort_a(1,n);        qsort_b(1,n);        sq[0]:=0;        for i:=1 to n do                sq[i]:=sq[i-1]+sqr(b[i]);        pre[0]:=0;        for i:=1 to n do                pre[i]:=pre[i-1]+b[i];        i:=1;        j:=0;        score_a:=0;        repeat                while (b[j+1]<a[i])and(j+1<=n) do inc(j);                score_a:=score_a+j*sqr(a[i])+sq[j]-2*a[i]*pre[j];                inc(i);        until i>n;        sq[0]:=0;        for i:=1 to n do                sq[i]:=sq[i-1]+sqr(a[i]);        pre[0]:=0;        for i:=1 to n do                pre[i]:=pre[i-1]+a[i];        i:=1;        j:=0;        score_b:=0;        repeat                while (a[j+1]<b[i])and(j+1<=n) do inc(j);                score_b:=score_b+j*sqr(b[i])+sq[j]-2*b[i]*pre[j];                inc(i);        until i>n;        writeln((score_a-score_b)/n:0:1);end.
0 0
原创粉丝点击