P5759 题解

· · 题解

这道题重在理解题意

选手编号依次为: 1,2...NN 为参赛总人数)。

x_{ij} 分别表示编号为 i 的选手第 j 项竞赛的成绩 (1 \le i \le N1 \le j \le 8) 。其它指标如下:

zm[j][i]+=abs(zn[k][i]-f[i]);
zm[j][i]=(zn[j][i]-f[i])/(zm[j][i]/n);
a[i].zf+=zm[i][j];
a[i].zf+=double(0.8*zm[i][j]);
位置分的计算
a[i].sum+=zn[i][j];
总位置分的计算

所以,一开始我用暴力DFS跑

突然60分有了(毕竟数据小)

所以可以得出 AC 算法

上代码!!!

其实我也是借鉴了题解区的大佬的算法,非常谔谔

#include<bits/stdc++.h>
#define LL long long //十年OI一场空,不开long long见祖宗
#define H 101
using namespace std;
#ifdef ONLINE_JUDGE
static char buf[1000000],*p1=buf,*p2=buf;
#define getchar() p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++
#endif
inline int read() //快读
{
    char ch=getchar();
    long long f=1,res=0;
    while(ch<'0'||ch>'9')
    {
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
        res=(res<<1)+(res<<3)+ch-48,ch=getchar();
    return res*f;
}
const int N=1e4+1;//其实就是10001
struct Sama{
    int id;
    double zf,sum;
};
Sama a[N];  
LL n;
int zn[N][H];
double zm[N][H],f[H];
bool cmp(Sama a1,Sama a2){//简简单单的排序
    if(a1.zf!=a2.zf){
        return a1.zf>a2.zf;
    }
    else if(a1.sum!=a2.sum){
        return a1.sum>a2.sum;
    }
    return a1.id<a2.id;
}
int main(){
    ios::sync_with_stdio(false);
    n=read();
    for(int i=1;i<=n;i++){
        for(int j=1;j<=8;j++){
            zn[i][j]=read();
        }
    }
    for(int i=1;i<=8;i++){  
        for(int j=1;j<=n;j++){
            f[i]+=zn[j][i];
        }
        f[i]=f[i]/n;
    }
    for(int i=1;i<=8;i++){
        for(int j=1;j<=n;j++){
            for(int k=1;k<=n;k++){
                zm[j][i]+=abs(zn[k][i]-f[i]); //计算前缀和
            }
            if(zm[j][i]!=0){
                zm[j][i]=(zn[j][i]-f[i])/(zm[j][i]/n);
            }
        }
    }
    for(int i=1;i<=n;i++){
        a[i].id=i;
        a[i].sum=0;
        for(int j=1;j<=3;j++){
            a[i].zf+=zm[i][j];
        }
        for(int j=4;j<=8;j++){
            a[i].zf+=double(0.8*zm[i][j]);
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=8;j++){
            a[i].sum+=zn[i][j];
        }
    }
    sort(a+1,a+n+1,cmp); //快排
    for(int i=1;i<=n;i++){
        cout<<a[i].id<<endl;
    }
    return 0;
}