题解 B4049:平均分计算

· · 题解

本题考查二维数组、顺序查找、分数约分,且要求选手写出规范、容易调试的代码。

要计算平均分,只要知道小 Y 报名的课程数量以及总分。

首先要把所有的课程信息用二维数组存储。这里,为了减少命名错误,建议大家直接使用题目中的变量名。

int n,p[45],ID;
int id[45][105],sc[45][105],w[45][105];
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&p[i]);
        for(int j=1;j<=p[i];j++)
            scanf("%d",&id[i][j]);
        for(int j=1;j<=p[i];j++)
            scanf("%d",&sc[i][j]);
        for(int j=1;j<=p[i];j++)
            scanf("%d",&w[i][j]);
    }
    scanf("%d",&ID);

接下来对于每门课程,要先判断小 Y 是否上了这门课,如果上了这门课,他的学号是第几小的。

这里考虑使用一重循环判断是否出现,其中 rkid 记录学号的排名sign 表示是否报名了这个课。

  int sums=0,sumc=0;
    for(int i=1;i<=n;i++){
        int rkid=0,sign=0;
        for(int j=1;j<=p[i];j++){
            if(id[i][j]==ID)
                sign=1;
            if(id[i][j]<=ID)
                rkid++;
        }
        if(sign==0)
            continue;

得到学号的排名后,我们能正确得到小 Y 在这门课上的活跃度,接下来要知道活跃度的排名,从而知道老师给出的分数。注意请仔细考虑并列,严格按照题目的定义

参考代码中,act 表示活跃度,rkact 表示活跃度的排名。

        int act=sc[i][rkid],rkact=1;
        for(int j=1;j<=p[i];j++)
            if(sc[i][j]>act)
                rkact++;
        sums+=w[i][rkact];
        sumc++;
    }

最后我们得到了课程数和总分,先算出整数部分 a 和小数部分 b/c,然后:

    int a=sums/sumc,b=sums%sumc,c=sumc;
    if(b==0)
        printf("%d\n",a);
    else{
        int gcd=1;
        for(int i=1;i<=b;i++)
            if(b%i==0 && c%i==0)
                gcd=i;
        printf("%d+%d/%d\n",a,b/gcd,c/gcd);
    }