DTOJ 1486:分数(score)

DTOJ 1486:分数(score)

【题目描述】

【输入】
      第一行包含两个正整数N和P,表示选手的个数以及精度要求。
      接下来的N行,每行包含一个0到100(闭区间)内的整数。
【输出】
      输出一个实数,取P位有效数字,下取整。

【样例输入】

5 4
100
20
15
10
0

【样例输出】

195.2

【提示】


【分析】
      这道题需要让你求出使偏差最小的难度和区分度的大小。根据题目下方的难度-区分度的图表,结合题意,可以发现偏差值与难度-区分度的关系为一个单峰函数。因此我们可以对其进行三分。由于有两个变量(难度,区分度),所以我们先固定一个变量,对另一个变量进行三分操作。在这里,我们最好先固定难度,先对区分度进行三分,求出当前难度下区分度最优的情况下的偏差值,然后根据偏差值的大小再对难度进行三分(也就是三分套三分的意思)。直接使用此方法即可。
【代码】

#include<bits/stdc++.h>
using namespace std;
const double eps=1e-9;
long double df_lf=0.0,df_rt=15.0,d,df_lm,df_rm,ds_lf,ds_rt,ds_lm,ds_rm;
int a[30],n,p;
inline long double sigma ( long double dfcl,long double disp )
{
    long double sum=0,idel=100;
    for ( int i=1;i<=n;i++ )
    {
        long double score=100/(1+exp(dfcl-disp*a[i]));
        if ( score<1e-12 ) sum+=(100.0-idel)*log(100/(100-score));
        else if ( score>=100 ) sum+=(idel*log(100/score));
        else sum+=(idel*log(100/score)+(100.0-idel)*log(100/(100-score)));
        idel-=d;
    }
    return sum;
}
inline void print ( long double val )
{
    long long w=1;
    int ups=0,used=0;
    while ( true )
    {
        if ( val/w<1 ) break;
        w*=10,ups++;
    }
    long long res=(long long)(val*pow(10,10-ups)),highest=1000000000;
    for ( int i=9;i>=10-p;i-- )
    {
        if ( i==9-ups ) putchar((i==9)?'0':'.');
        cout<<res/highest;res%=highest;used++;highest/=10;
    }
    while ( used<ups ) putchar('0'),used++;
}
inline int read ( void )
{
    int x=0;char ch=getchar();
    while ( !isdigit(ch) ) ch=getchar();
    for ( x=ch-48;isdigit(ch=getchar()); ) x=(x<<1)+(x<<3)+ch-48;
    return x;
}
int main()
{
    scanf("%d%d",&n,&p);d=100.0/(n-1);
    for ( int i=1;i<=n;i++ ) scanf("%d",&a[i]);
    while ( df_rt-df_lf>eps )
    {
        df_lm=df_lf+(df_rt-df_lf)/3.0,df_rm=df_rt-(df_rt-df_lf)/3.0;
        ds_lf=0.0,ds_rt=1.0;
        while ( ds_rt-ds_lf>eps )
        {
            ds_lm=ds_lf+(ds_rt-ds_lf)/3.0,ds_rm=ds_rt-(ds_rt-ds_lf)/3.0;
            if ( sigma(df_lm,ds_lm)<sigma(df_lm,ds_rm) ) ds_rt=ds_rm;
            else ds_lf=ds_lm;
        }
        double min_lm=sigma(df_lm,ds_lm);
        ds_lf=0.0,ds_rt=1.0;
        while ( ds_rt-ds_lf>eps )
        {
            ds_lm=ds_lf+(ds_rt-ds_lf)/3.0,ds_rm=ds_rt-(ds_rt-ds_lf)/3.0;
            if ( sigma(df_rm,ds_lm)<sigma(df_rm,ds_rm) ) ds_rt=ds_rm;
            else ds_lf=ds_lm;
        }
        double min_rm=sigma(df_rm,ds_lm);
        if ( min_lm<min_rm ) df_rt=df_rm;
        else df_lf=df_lm;
    }
    print(sigma(df_lm,ds_lm));
    return 0;
}

猜你喜欢

转载自blog.csdn.net/dtoi_rsy/article/details/80939619
今日推荐