PAT---A1012. The Best Rank (25)

来源:互联网 发布:电子教室软件哪个好 编辑:程序博客网 时间:2024/06/05 07:32

题目要求:
To evaluate the performance of our first year CS majored students, we consider their grades of three courses only: C - C Programming Language, M - Mathematics (Calculus or Linear Algebra), and E - English. At the mean time, we encourage students by emphasizing on their best ranks – that is, among the four ranks with respect to the three courses and the average grade, we print the best rank for each student.

For example, The grades of C, M, E and A - Average of 4 students are given as the following:

StudentID C M E A
310101 98 85 88 90
310102 70 95 88 84
310103 82 87 94 88
310104 91 91 91 91
Then the best ranks for all the students are No.1 since the 1st one has done the best in C Programming Language, while the 2nd one in Mathematics, the 3rd one in English, and the last one in average.

Input

Each input file contains one test case. Each case starts with a line containing 2 numbers N and M (<=2000), which are the total number of students, and the number of students who would check their ranks, respectively. Then N lines follow, each contains a student ID which is a string of 6 digits, followed by the three integer grades (in the range of [0, 100]) of that student in the order of C, M and E. Then there are M lines, each containing a student ID.

Output

For each of the M students, print in one line the best rank for him/her, and the symbol of the corresponding rank, separated by a space.

The priorities of the ranking methods are ordered as A > C > M > E. Hence if there are two or more ways for a student to obtain the same best rank, output the one with the highest priority.

If a student is not on the grading list, simply output “N/A”.

Sample Input
5 6
310101 98 85 88
310102 70 95 88
310103 82 87 94
310104 91 91 91
310105 85 90 90
310101
310102
310103
310104
310105
999999
Sample Output
1 C
1 M
1 E
1 A
3 A
N/A

参考代码:

#include <iostream>#include <cstdio>#include <algorithm>using namespace std;struct student{    int ID;    int grade[4];//用来存储平均分和C,M,E的分数}stu[2010];//用来控制输出,因为输出的优先级顺序而采用这种数组的构造方法,A>C>M>Echar out[4] = {'A','C','M','E'};//rank1[ID][0]为学号为ID的学生的平均分的排名int rank1[1000000][4] = {0};int now = 0;//按照从高到低构造cmp函数,详细的比较函数构造方法参考上篇博文:PAT---A1062. Talent and Virtue (25)bool cmp(student a,student b){    return a.grade[now]>b.grade[now];}int main(){    int M,N;    cin >> N>>M;    for(int i=0;i<N;i++)    {   //使用scanf为了减少程序运行时间防止运行超时        scanf("%d%d%d%d",&stu[i].ID,&stu[i].grade[1],&stu[i].grade[2],&stu[i].grade[3]);        stu[i].grade[0] = (stu[i].grade[1]+stu[i].grade[2]+stu[i].grade[3])/3.0+0.5;    }    //对grade进行从高到低排序后,对rank1进行赋值排名    for(now = 0;now<4;now++)    {        sort(stu,stu+N,cmp);    //使用sort函数进行排序,如有疑问参考上篇博文:PAT---A1062. Talent and Virtue (25)        rank1[stu[0].ID][now] = 1;//假设经过排序后的第一个人的排名为第1        for(int i=1;i<N;i++)        {            //如果此人和前一个人分数一样,则排名相同,否则排名加1            //且此判别式可以保证当两个人排名相同时,如排名为1 2 3 3 5 而不是 1 2 3 3 4            if(stu[i].grade[now] == stu[i-1].grade[now])                rank1[stu[i].ID][now] = rank1[stu[i-1].ID][now];            else                rank1[stu[i].ID][now] = i + 1;        }    }    int query;    int q = 0;      //控制输出队列    char s[7000];   //存储输出队列    for(int i=0;i<M;i++)    {        scanf("%d",&query);        //当平均分为0时表明查找的学号不存在        if(rank1[query][0] == 0)            {                //控制输出队列,即全部获取输入后再统一输出,而不是边输入边输出                s[q] = 'N';                s[q+1] = '/';                s[q+2] = 'A';                q = q+3;            }        else        {            int k=0;            for(int j=0;j<4;j++)            {                //判断4门课中排名最小的课的序号(即成绩最好的那门课的序号)                if(rank1[query][j]<rank1[query][k])                    k = j;            }            //控制输出队列            s[q] = rank1[query][k]+'0';            s[q+1] = ' ';            s[q+2] = out[k];            q = q+3;        }    }    for(int i=0;i<q;i++)       {            cout <<s[i];            if((i%3==2)&&(i!=q-1))                cout <<endl;       }    return 0;}

本题使用学生的ID作为数组下标,如果学生的ID过长,则数组的长度可能过大,这时我们可以采用更一般的方法。

一般方法的解题思路:
解题思路就是:我们在学生的信息,也就是创建的结构体中增加了一个额外的附加信息用来标注结构体,就是order,order用来表示结构体的序列号。因为经过sort排序后,stu[]数组的顺序完全被改变,所以只有使用order来标识每一个学生,这时我们使用一个新的数组即rank1[][]这个二重数组来表示一个学生的排名,rank1[0]表示序号为0的学生,所以rank1[0][0]表示序号为0的学生的平均分在班级的排名,rank1[0][1]表示序号为0的学生的C在班级的排名。。。。。。然后根据输入的学号检索到此学号对应的order,再输出这个order的排名中最小的课

#include <iostream>#include <cstdio>#include <algorithm>using namespace std;struct student{    int order;    int ID;    int grade[4];//用来存储平均分,C,M,E的分数}stu[2010];//用来控制输出,因为输出的优先级顺序而采用这种数组的构造方法,A>C>M>Echar out[4] = {'A','C','M','E'};//rank1[0][0]为order是0的学生的平均分所占的名次int rank1[2010][4] = {0};int now = 0;//按照从高到低构造cmp函数,详细的比较函数构造方法参考上篇博文:PAT---A1062. Talent and Virtue (25)bool cmp(student a,student b){    return a.grade[now]>b.grade[now];}int main(){    int M,N;    cin >> N>>M;    for(int i=0;i<N;i++)    {        stu[i].order = i;         //使用scanf为了减少程序运行时间防止运行超时        scanf("%d%d%d%d",&stu[i].ID,&stu[i].grade[1],&stu[i].grade[2],&stu[i].grade[3]);        stu[i].grade[0] = (stu[i].grade[1]+stu[i].grade[2]+stu[i].grade[3])/3.0+0.5;    }    //对grade进行从高到低排序后,对rank1进行赋值排名    for(now = 0;now<4;now++)    {        sort(stu,stu+N,cmp);    //使用sort函数进行排序,如有疑问参考上篇博文:PAT---A1062. Talent and Virtue (25)        rank1[stu[0].order][now] = 1;//假设经过排序后的第一个人的排名为第1        for(int i=1;i<N;i++)        {            //如果此人和前一个人分数一样,则排名相同,否则排名加1            //且此判别式可以保证当两个人排名相同时,如排名为1 2 3 3 5 而不是 1 2 3 3 4            if(stu[i].grade[now] == stu[i-1].grade[now])                rank1[stu[i].order][now] = rank1[stu[i-1].order][now];            else                rank1[stu[i].order][now] = i + 1;        }    }    int query;    int q = 0;      //控制输出队列    char s[7000];   //存储输出队列    for(int i=0;i<M;i++)    {        int a = 0;        scanf("%d",&query);        for(int i = 0;i<N;i++)        {            if(query == stu[i].ID)            {                int k = 0;                for(int j=0;j<4;j++)                {                //判断4门课中排名最小的课的序号(即成绩最好的那门课的序号)赋值给k                if(rank1[stu[i].order][j]<rank1[stu[i].order][k])                    k = j;                }            //控制输出队列,即全部获取输入后再统一输出,而不是边输入边输出                s[q] = rank1[stu[i].order][k]+'0';                s[q+1] = ' ';                s[q+2] = out[k];                q = q+3;            }            else            {               a++;            }        }        if(a == N)        {            s[q] = 'N';            s[q+1] = '/';            s[q+2] = 'A';            q = q+3;        }    }    for(int i=0;i<q;i++)       {            cout <<s[i];            if((i%3==2)&&(i!=q-1))                cout <<endl;       }    return 0;}
0 0
原创粉丝点击