题解 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++;
}
最后我们得到了课程数和总分,先算出整数部分
- 如果
b=0 ,那么小数部分是0 ,直接输出a 。 - 否则要对
b/c 约分,也就是先求出最大公约数gcd ,然后再把b,c 都除以这个gcd 。
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);
}