0
点赞
收藏
分享

微信扫一扫

PAT 乙级 1080 MOOC期终成绩 (25 分) c语言 测试点分析

萨摩斯加士奇 2022-01-23 阅读 87

首先说一下最后一个测试点的问题,要注意最终成绩就是四舍五入过的整数,也就是说98.6和98.7成绩是一样的,着实被恶心到了,害我搞了半天。

题目

对于在中国大学MOOC(http://www.icourse163.org/ )学习“数据结构”课程的学生,想要获得一张合格证书,必须首先获得不少于200分的在线编程作业分,然后总评获得不少于60分(满分100)。总评成绩的计算公式为 G=(Gmid−term​×40%+Gfinal​×60%),如果 Gmid−term​>Gfinal​;否则总评 G 就是 Gfinal​。这里 Gmid−term​ 和 Gfinal​ 分别为学生的期中和期末成绩。

现在的问题是,每次考试都产生一张独立的成绩单。本题就请你编写程序,把不同的成绩单合为一张。

输入格式:

输入在第一行给出3个整数,分别是 P(做了在线编程作业的学生数)、M(参加了期中考试的学生数)、N(参加了期末考试的学生数)。每个数都不超过10000。

接下来有三块输入。第一块包含 P 个在线编程成绩 Gp​;第二块包含 M 个期中考试成绩 Gmid−term​;第三块包含 N 个期末考试成绩 Gfinal​。每个成绩占一行,格式为:学生学号 分数。其中学生学号为不超过20个字符的英文字母和数字;分数是非负整数(编程总分最高为900分,期中和期末的最高分为100分)。

输出格式:

打印出获得合格证书的学生名单。每个学生占一行,格式为:

学生学号 Gp​ Gmid−term​ Gfinal​ G

如果有的成绩不存在(例如某人没参加期中考试),则在相应的位置输出“−1”。输出顺序为按照总评分数(四舍五入精确到整数)递减。若有并列,则按学号递增。题目保证学号没有重复,且至少存在1个合格的学生。

 输出样例:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct student{
    char name[25];       /*储存学号*/
    int p;               /*储存在线编程成绩*/
    int m;               /*储存期中考试成绩*/
    int n;               /*储存期末成绩*/
    int zong;            /*储存期终成绩*/
    int check;           /*是否合格*/
}stu;
int comp1(const void* a,const void* b);    /*按照学号升序排列*/
int comp2(const void* a,const void* b);    /*排序总函数*/
int comp3(const void* a,const void* b);    /*按学号查找函数*/
int main(){
    int p,m,n,i=0,x=0;    /*储存各类考试成绩*/
    int mp,mm,mn;
    char name[25];
    stu a[100000];        /*这里是100000个学生*/
    stu *dent;
    scanf("%d %d %d",&p,&m,&n);
    while(p--)
        {scanf("%s %d",name,&mp);
         getchar();
         strcpy(a[i].name,name);
         a[i].p=mp;
         a[i].m=-1;      /*其他两项成绩初始化,默认没有*/
         a[i].n=-1;
         i++;
        }
    qsort(a,i,sizeof(stu),comp1);
    while(m--)
        {scanf("%s %d",name,&mm);
         getchar();
         dent=(stu*)bsearch(name,a,i,sizeof(stu),comp3);
         if(dent!=0)         /*若在线编程没有成绩,则一定不合格,不考虑*/
             dent->m=mm;
        }
    while(n--)
        {scanf("%s %d",name,&mn);
         getchar();
         dent=(stu*)bsearch(name,a,i,sizeof(stu),comp1);
         if(dent!=0)
             dent->n=mn;
        }
    for(x=0;x<i;x++)      /*这个循环计算最终成绩,并判定是否合格*/
        {if(a[x].m<a[x].n)
            {a[x].zong=a[x].n;
             if(a[x].zong>=60&&a[x].p>=200)
                {a[x].check=1;
                }
            else
                a[x].check=0;
            continue;
            }
        a[x].zong=(int)(a[x].m*0.4+a[x].n*0.6+0.5);   /*四舍五入后储存*/
        if(a[x].zong+0.5>=60&&a[x].p>=200)
            {a[x].check=1;
            }
         else
            a[x].check=0;
        }
    qsort(a,i,sizeof(stu),comp2);          /*排序*/
    for(x=0;x<i&&a[x].check==1;x++)        /*输出*/
        printf("%s %d %d %d %d\n",a[x].name,a[x].p,a[x].m,a[x].n,a[x].zong);
}
int comp1(const void* a,const void* b)
    {stu* x=(stu*)a;
     stu* y=(stu*)b;
     return strcmp(x->name,y->name);    /*按名字升序*/
    }
int comp2(const void* a,const void* b)
    {stu* x=(stu*)a;
     stu* y=(stu*)b;
    if(x->check != y->check)         /*合格在前*/
        return y->check - x->check;
     else if(x->zong != y->zong)     /*最终成绩高的在前*/
         return y->zong - x->zong;
     else                             /*按名字升序*/
         return strcmp(x->name,y->name);
    }
int comp3(const void* a,const void* b)
    {char *x=(char*)a;
    stu *y=(stu*)b;
     return strcmp(x,y->name);        /*查找*/
    }

 需要注意的地方写在开头和注释里了,之前换过一种方法,但运行时间半斤八两,这个代码相对简洁。

 

举报

相关推荐

0 条评论