每次 PAT 考试结束后,考试中心都会发布一个考生单位排行榜。本题就请你实现这个功能。
输入格式:
输入第一行给出一个正整数N(<=105),即考生人数。随后N行,每行按下列格式给出一个考生的信息:
准考证号 得分 学校
其中“准考证号”是由6个字符组成的字符串,其首字母表示考试的级别:“B”代表乙级,“A”代表甲级,“T”代表顶级;“得分”是 [0,100] 区间内的整数;“学校”是由不超过6个英文字母组成的单位码(大小写无关)。注意:题目保证每个考生的准考证号是不同的。
输出格式:
首先在一行中输出单位个数。随后按以下格式非降序输出单位的排行榜:
排名 学校 加权总分 考生人数
其中“排名”是该单位的排名(从1开始);“学校”是全部按小写字母输出的单位码;“加权总分”定义为“乙级总分/1.5 + 甲级总分 + 顶级总分*1.5”的整数部分;“考生人数”是该属于单位的考生的总人数。
学校首先按加权总分排行。如有并列,则应对应相同的排名,并按考生人数升序输出。如果仍然并列,则按单位码的字典序输出。
输入样例:10 A57908 85 Au B57908 54 LanX A37487 60 au T28374 67 CMU T32486 24 hypu A66734 92 cmu B76378 71 AU A47780 45 lanx A72809 100 pku A03274 45 hypu输出样例:
5 1 cmu 192 2 1 au 192 3 3 pku 100 1 4 hypu 81 2 4 lanx 81 2
自己写的超时,不太会优化,如下:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef struct{
int sort;
char name[100];
double score;
int stunum;
}S;
S school[100005];
int cmp(S a,S b)
{
if(a.score!=b.score)
return a.score>b.score?1:0;
else if(a.stunum!=b.stunum)
return a.stunum<b.stunum?1:0;
else if(strcmp(a.name,b.name)<0)
return 1;
else
return 0;
}
int main()
{
int N,grade,flag;
int snum=0;//当前学校数量
char s[20];
char c[20];
scanf("%d",&N);
while(N--)
{
flag=0;//默认该考生所在学校并未存于已知名单中
scanf("%s",c);
scanf("%d",&grade);
scanf("%s",s);
int length=strlen(s); //学校名转为小写
for(int i=0;i<length;i++)
if(s[i]>='A'&&s[i]<='Z')
s[i]=s[i]+32;
for(int i=1;i<=snum;i++)
{
// printf("%s %s\n",school[i].name,s);
if(strcmp(school[i].name,s)==0)
{
// printf("equal");
if(c[0]=='B')
school[i].score+=(double)grade/1.5;
else if(c[0]=='A')
school[i].score+=grade;
else if(c[0]=='T')
school[i].score+=(double)grade*1.5;
school[i].stunum++;
flag=1;//已经计入某学校
break;
}
}
if(flag==0) //已知名单中没有该校
{
snum++;
// printf("snum=%d\n",snum);
strcpy(school[snum].name,s);
if(c[0]=='B')
school[snum].score+=(double)grade/1.5;
else if(c[0]=='A')
school[snum].score+=grade;
else if(c[0]=='T')
school[snum].score+=(double)grade*1.5;
school[snum].stunum++;
}
}
sort(school+1,school+1+snum,cmp);
school[1].sort=1;
printf("%d\n",snum);
printf("%d %s %d %d\n",school[1].sort,school[1].name,(int)school[1].score,school[1].stunum);
for(int i=2;i<=snum;i++)
{
if((int)school[i].score==(int)school[i-1].score)
school[i].sort= school[i-1].sort;
else
school[i].sort=i;
printf("%d %s %d %d\n",school[i].sort,school[i].name,(int)school[i].score,school[i].stunum);
}
return 0;
}
大神的
AC
代码:
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <map>
#include <string>
#include <vector>
using namespace std;
struct School {
string name;
int score;
int people;
School(string a, int b, int c)
{
name = a;
score = b;
people = c;
}
};
bool cmp(const School& a, const School& b)
{
if (a.score == b.score) {
if (a.people == b.people) {
return a.name < b.name;
} else {
return a.people < b.people;
}
} else {
return a.score > b.score;
}
}
string lower(string& s)
{
for (unsigned int i = 0; i < s.length(); i++) {
if (s[i] >= 'A' && s[i] <= 'Z') {
s[i] = s[i] - 'A' + 'a';
}
}
return s;
}
int main()
{
int n;
cin >> n;
map<string, double> m;
map<string, int> cnt;
for (int i = 0; i < n; i++) { // input and calculate
string id, school;
int score;
cin >> id >> score >> school;
cnt[lower(school)]++;
switch (id[0]) {
case 'B':
m[lower(school)] += score / 1.5;
break;
case 'A':
m[lower(school)] += score;
break;
case 'T':
m[lower(school)] += score * 1.5;
break;
default:
break;
}
}
vector<School> v;
for (auto it = m.begin(); it != m.end(); it++) {
School s(it->first, int(it->second), cnt[it->first]);
v.push_back(s);
}
sort(v.begin(), v.end(), cmp);
int rk = 0;
int pre_score = -1;
printf("%ld\n", v.size());
for (unsigned int i = 0; i < v.size(); i++) {
if (v[i].score != pre_score) {
rk = i + 1;
}
printf("%d %s %d %d\n", rk, v[i].name.c_str(), v[i].score, v[i].people);
pre_score = v[i].score;
}
return 0;
}