JZ3055比赛

来源:互联网 发布:猎豹刷票软件 编辑:程序博客网 时间:2024/05/21 12:48

题目:

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


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


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

分析:

根据期望的和=和的期望,只需把A队每个人的期望得分减去B队每个人的期望得分即为答案。

A队某人X的期望得分为(其中y为B队中实力低于X的人,P代表X和Y相遇的概率)。

显然任意两个人相遇的概率是相等的,=两人第一场相遇的概率+两人第一场不相遇的概率*两人第二场相遇的概率+……。

30分做法:任意枚举两个人算期望。

100分做法:排序后只需枚举一个人i,用一个指针指着另一  队中实力比i弱的里面最强的人,维护实力值的前缀和,实力值平方的前缀和即可算出期望。

显然指针只可能向右移动,所以这一步是线性的。

附上代码:

const
  maxn=50000;


type
  arr=array [0..maxn] of int64;


var
  a,b,ans1,ans2:arr;
  ans:extended;
  n:longint;


procedure init;
var
  i:longint;
begin
  readln(n);
  for i:=1 to n do
    read(a[i]);
  for i:=1 to n do
    read(b[i]);
end;


procedure qsort(var temp:arr; l,r:longint);
var
  i,j,k,mid:longint;
begin
  i:=l; j:=r; mid:=temp[(l+r) div 2];
  repeat
    while temp[i]<mid do
      inc(i);
    while temp[j]>mid do
      dec(j);
    if i<=j then
      begin
        k:=temp[i];
        temp[i]:=temp[j];
        temp[j]:=k;
        inc(i);
        dec(j);
      end;
  until i>j;
  if l<j then
    qsort(temp,l,j);
  if i<r then
    qsort(temp,i,r);
end;


procedure main;
var
  i,j:longint;
begin
  qsort(a,1,n);
  qsort(b,1,n);
  for i:=1 to n do
    begin
      ans1[i]:=ans1[i-1]+b[i];
      ans2[i]:=ans2[i-1]+b[i]*b[i];
    end;
  for i:=1 to n do
    begin
      while (j<n) and (a[i]>b[j+1]) do
        inc(j);
      ans:=ans+a[i]*a[i]*(2*j-n);
      ans:=ans+2*ans2[j]-ans2[n];
      ans:=ans-2*a[i]*(2*ans1[j]-ans1[n]);
    end;
  write(ans/n:0:1);
end;


begin
  init;
  main;
end.

0 0
原创粉丝点击