关于用 C++ 实现 CF rating
  • 板块灌水区
  • 楼主StarryAbyss
  • 当前回复3
  • 已保存回复3
  • 发布时间2023/3/10 22:42
  • 上次更新2023/10/23 21:59:26
查看原帖
关于用 C++ 实现 CF rating
821638
StarryAbyss楼主2023/3/10 22:42

先输入一个整数 nn 表示人数,接下来 nn 个数,第 ii 个数表示排名第 ii 人的 rating,输出它们的 rating 变化值。

颓了 44 行代码,发现有 bug。当 nn 较小,而 rating 之间的差距较大时,比如 2 4000 0,rating 的极大值会变得非常大。

大概发现的问题出在哪里:当两个人的 rating 差为 40004000 时,rating 高的一位用户获胜的概率只有 14000\dfrac{1}{4000}10910^{-9} 的精度误差就不准确了。

求如何做出一个准确且无 bug 的 C++ CF rating 系统?

贴代码:

#include<bits/stdc++.h>
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#define int long long
using namespace std;
int n,a[100001];
double rk[100001];
int inf=1e9;
double bf(int p,double m){
    double l=-inf,r=inf,mid;
    while(l<=r){
        mid=(l+r)/2;
        double rk=1;
        for(int i=1;i<=n;i++){
            if(i==p)continue;
            rk+=1.0/(1.0+pow(10,(mid-a[i])/400.0));
        }
        if(fabs(rk-m)<1e-9)return mid;
        else if(rk>m)l=mid;
        else r=mid;
    }
    return mid;
}
signed main()
{
    //freopen("1.out","w",stdout);
    while(1){
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>a[i];
        }
        fill(rk+1,rk+n+1,1);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(j==i)continue;
                rk[i]+=1.0/(1.0+pow(10,(a[i]-a[j])/400.0));
            }
        }
        for(int i=1;i<=n;i++){
            double m=sqrt(i*rk[i]);
            printf("%5d %5d %c%-5d %-5d\n",i,a[i],((int)round(a[i]+(bf(i,m)-a[i])/2)-a[i]>=0?'+':'-'),abs((int)round(a[i]+(bf(i,m)-a[i])/2)-a[i]),(int)round(a[i]+(bf(i,m)-a[i])/2));
        }
    }
}
2023/3/10 22:42
加载中...