1012 The Best Rank (25分)

012 The Best Rank (25分)
 

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 Algrbra), 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 CME 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 Specification:

Each input file contains one test case. Each case starts with a line containing 2 numbers N and M (≤), 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 CM and E. Then there are M lines, each containing a student ID.

Output Specification:

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



题目 做的太少,没经验
失误1
本来想着用学生id做数组下标
但是看到题目说学生的学号是六位数,有点蒙了
这岂不是要开一百万的数组?
这么大会不会占用太多内存?
种种顾虑涌上心头
最终没有选择开这么大的数组,而是用的及笨的方法
导致题目做起来非常复杂,棘手,混乱,定义了三种结构体

失误2
结构体排序理解的不够透彻
题目需要对同一个结构体数组,排序安装四门成绩排序四次
结果我写了四个cmp函数,这还是sort排序不熟练导致的
其实在cmp函数内部添加一个参数就好,这个参数做全局变量
int now; //cmp函数中使用,表示当前按now号分数排序stu数组

bool cmp(student a,student b)
{
    return a.grade[now]>b.grade[now];
}

 


题解见https://blog.csdn.net/mayuejike/article/details/86560308


看完
题解,代码全删,重新做一遍此题

事实证明,自己一开始写的代码,空间复杂度确实是低的,只有几百k,参考题解之后的新代码,虽然简洁,但是空间每次都是16000kb
但是从编写效率上来看,拿空间复杂度换编写效率还是值得的

 

 


 

 



一开始自己写的代码,卡了2,3测试点
参考题解写的代码,提交之后,居然卡的仍然是2,3测试点
这说明自己的代码是没问题的

下面就来到本题目的最大坑点了

排名规则
 1、可能存在两个或多个学生分数相同的情况,排名顺序是1、1、3、4、5而不是1、2、3、4、5,所以不是简单的数组下标相加1

这里是非常坑人的地方,因为题目并没有说排序规则,
(我没有具体计算测试数据,也许给出暗示了

于是我修改了排名的规则,直接ac

 

附上最后的代码,心累

 

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 typedef struct student{
 6     int id;
 7     int score[5];
 8 }student;
 9 
10 student stu[2010];
11 int ranklist[1000000][4];//记录每一位学生的,四门成绩的排名,四门成绩挨个遍历就行0-A,1-C,2-M,3-E,不做sort
12 //记录当前是哪一门成绩
13 int flag;
14 
15 int cmp(student s1,student s2){
16     return s1.score[flag] > s2.score[flag];
17 }
18 
19 int main(){
20     int N,M;
21     cin>>N>>M;
22     //先做N次成绩录入
23     int id;
24     for(int i=0;i<N;i++){
25         cin>>stu[i].id;
26         int sum=0;
27         for(int j=1;j<=3;j++){
28             cin>>stu[i].score[j];
29             sum+=stu[i].score[j];
30         }
31         stu[i].score[0] = sum/3;//平均分四舍五入
32     }
33 
34     //进行四次排序
35     memset(ranklist,0,sizeof(ranklist));
36 
37     //排名是个大坑,题目信息缺失
38     //能存在两个或多个学生分数相同的情况,排名顺序是1、1、3、4、5
39     //而不是1、2、3、4、5,所以不是简单的数组下标相加1
40     for(flag=0;flag<=3;flag++){
41         sort(stu,stu+N,cmp);
42         ranklist[stu[0].id][flag] = 1;
43 
44         int len = 0;//记录成绩连续相同的步长
45         for(int i=1;i<N;i++){
46             //成绩相同
47             //学号为id的学生,第flag门成绩的排名
48             if(stu[i].score[flag] == stu[i-1].score[flag]){
49                 ranklist[stu[i].id][flag] = ranklist[stu[i-1].id][flag];
50                 len++;
51             }
52             else {
53                 ranklist[stu[i].id][flag] = ranklist[stu[i-1].id][flag] +len+1;
54             }
55         }
56     }
57     //再做M次成绩查询
58     char course[5] = "ACME";
59     for(int i=0;i<M;i++){
60         cin>>id;
61         int r=ranklist[id][0];
62         int course_th=0;//记录是第几门
63         int flag = 1;//记录是否存在id
64         for(int i=0;i<=3;i++){
65             //cout<<ranklist[id][i]<<" ";
66             if(ranklist[id][i] < r){
67                 r = ranklist[id][i];
68                 course_th = i;
69             }
70             if(ranklist[id][i] == 0){
71                 flag = 0;
72                 break;
73             }
74         }
75         //cout<<endl;
76         if(flag==0){
77             cout<<"N/A"<<endl;
78         }
79         else{
80             cout<<r<<" "<<course[course_th]<<endl;
81         }
82     }
83 
84 }
View Code

 

 

 

 

 下面这个是自己写的初始代码,没有通过2,3(还是排名的原因),也贴一下

 

  1 #include <bits/stdc++.h>
  2 
  3 using namespace std;
  4 
  5 
  6 typedef struct student{
  7     int id;
  8     int A;
  9     int C;
 10     int M;
 11     int E;
 12 }student;
 13 typedef struct rrank{
 14     int nber;
 15     char course;
 16 }rrank;
 17 typedef struct stu_result{
 18     int id;
 19     rrank rk[4];
 20 }stu_result;
 21 int cmpA(student s1,student s2){
 22     return s1.A>s2.A;
 23 }
 24 
 25 int cmpC(student s1,student s2){
 26     return s1.C>s2.C;
 27 }
 28 int cmpM(student s1,student s2){
 29     return s1.M>s2.M;
 30 }
 31 int cmpE(student s1,student s2){
 32     return s1.E>s2.E;
 33 }
 34 //对每一个学生的四科排名进行综合排序,取名次最高的
 35 int cmprrank(rrank r1,rrank r2){
 36     return r1.nber < r2.nber;
 37 }
 38 int stroage_rrank(student stu[],stu_result res[],int n,int course_id,char course){
 39     for(int i=0;i<n;i++){
 40         for(int j=0;j<n;j++){
 41             if(stu[i].id == res[j].id){
 42                 res[j].rk[course_id].nber = i+1;
 43                 res[j].rk[course_id].course = course;
 44             }
 45         }
 46     }
 47     return 0;
 48 
 49 }
 50 int main(){
 51 
 52     int n,m;
 53     cin>>n>>m;
 54     student stu[n];
 55     for(int i=0;i<n;i++){
 56         cin>>stu[i].id>>stu[i].C>>stu[i].M>>stu[i].E;
 57         stu[i].A = (stu[i].C+stu[i].M+stu[i].E)/3;
 58     }
 59     int id[m];
 60     for(int i=0;i<m;i++){
 61         cin>>id[i];
 62     }
 63 
 64     stu_result res[n];
 65     for(int i=0;i<n;i++){
 66         res[i].id = stu[i].id;
 67     }
 68 
 69     sort(stu,stu+n,cmpA);
 70     stroage_rrank(stu,res,n,0,'A');
 71     sort(stu,stu+n,cmpC);
 72     stroage_rrank(stu,res,n,1,'C');
 73     sort(stu,stu+n,cmpM);
 74     stroage_rrank(stu,res,n,2,'M');
 75     sort(stu,stu+n,cmpE);
 76     stroage_rrank(stu,res,n,3,'E');
 77 
 78     //对每一个学生的四科排名进行综合排序,取名次最高的
 79     for(int i=0;i<n;i++){
 80         sort(res[i].rk,res[i].rk+4,cmprrank);
 81         //cout<<res[i].id<<res[i].rk[0].course<<res[i].rk[1].course<<res[i].rk[2].course<<res[i].rk[3].course<<endl;
 82     }
 83 
 84     //输出结果
 85     for(int i=0;i<m;i++){
 86         int flag = 0;
 87         for(int j=0;j<n;j++){
 88             if(id[i]==res[j].id){
 89                 cout<<res[j].rk[0].nber<<" "<<res[j].rk[0].course<<endl;
 90                 flag = 1;
 91                 break;
 92             }
 93         }
 94         if(flag == 0){
 95             cout<<"N/A"<<endl;
 96         }
 97     }
 98     return 0;
 99 
100 
101 }
View Code

 



 
posted @ 2020-08-22 11:21  houyz  阅读(150)  评论(0)    收藏  举报