题目链接
《算法笔记》上面的思路可能是一种套路,用空间来换时间。
《算法笔记》上的代码:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
struct Stu{
int id;
int grade[4];
}stu[2010];
char course[]="ACME";
int Rank[10000000][4]={0};
int now;
bool cmp(Stu a,Stu b){
return a.grade[now]>b.grade[now];
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
for (int i=0; i<n; i++){
scanf("%d%d%d%d",&stu[i].id,&stu[i].grade[1],&stu[i].grade[2],&stu[i].grade[3]);
stu[i].grade[0]=round((stu[i].grade[1]+stu[i].grade[2]+stu[i].grade[3])/3);
}
for (now =0; now<4; now++){
sort(stu,stu+n,cmp);
Rank[stu[0].id][now]=1;
for (int i=1; i<n; i++){
if (stu[i].grade[now]==stu[i-1].grade[now]){
Rank[stu[i].id][now]=Rank[stu[i-1].id][now];
}else {
Rank[stu[i].id][now]=i+1;
}
}
}
int query;
for (int i=0; i<m; i++){
scanf("%d",&query);
if (Rank[query][0]==0){
printf("N/A\n");
}else {
int k=0;
for (int j=0; j<4; j++){
if (Rank[query][j]<Rank[query][k])
k=j;
}
printf("%d %c\n",Rank[query][k],course[k]);
}
}
}
这种思路不难,但是也有局限性,假如学生的学号不是六位数,而是十位数,或者带有字母,那么用Rank数组就无能为力了,有一种更一般的思路:
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
struct Stu{
int id,grade[4];
}stu[2010];
char course[]="ACME";
int now;
bool cmp(Stu a, Stu b){
return a.grade[now]>b.grade[now];
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
for (int i=0; i<n; i++){
scanf("%d%d%d%d",&stu[i].id,&stu[i].grade[1],&stu[i].grade[2],&stu[i].grade[3]);
stu[i].grade[0]=round((stu[i].grade[1]+stu[i].grade[2]+stu[i].grade[3])/3);
}
for (int i=0; i<m; i++){
int temp;
scanf("%d",&temp);
int j,k;
for (j=0; j<n; j++){
if (temp==stu[j].id){
int best=n+1,bestCourse=-1;
int tempGrade[4];
for (int p=0; p<4; p++){
tempGrade[p]=stu[j].grade[p];
}
for (now=0; now<4; now++){
sort(stu,stu+n,cmp);
for (k=0; k<n; k++){
if (stu[k].grade[now]==tempGrade[now]) break;
}
if (k<best) {
best=k;
bestCourse=now;
}
}
printf("%d %c\n",best+1,course[bestCourse]);
break;
}
}
if (j==n) printf("N/A\n");
}
}
第二个代码,可以应付各种情况的 id ,对字符型的id,也只需要稍微改动就可以,更具有一般性。