目的:根据学生的表现,生成机构的排名
输入:
N <= 100000 测试人数
N个人的信息:
ID SCORE SCHOOL
id 是一个6个字符的字符串,第一个字符代表测试的等级。B表示基础等级,A表示高级等级,T表示顶级。
score 是一个整数[0,100]
school 机构的代码,一个不超过6个英文字母
id 是独一无二的
输出:
第一行输出总的机构的数量
然后输出机构的排名,非减的,以下格式
RANK SCHOOL TWS Ns
rank 从1开始,机构排名
school 机构代码,用小写
tws 总的加权分数,ScoreB/1.5 + ScoreA + ScoreT*1.5,这些分数,是属于这个学校参加该等级考试的总分
ns 这个机构参加考试的人数
机构根据Tws 排名,如果有一样的,那就排名一样,然后以Ns的增长序列输出。如果仍然有一样的,按照字母顺序输出。
算法:
写一个函数统一将学校名改为小写。
然后用一个map记录学校的编号。
一个用数组存学校名字和排名,分数,人数;
然后在排序,先按分数排名,分一样按人少到多排名,还一样按名字字母顺序排名。
#include<stdio.h> #include<iostream> #include<map> #include<vector> #include<string> #include<algorithm> using namespace std; #define B(i) ((i)*4) #define A(i) ((i)*6) #define T(i) ((i)*9) struct school{ string name; int tws; int num; }temp; map<string,int> mp; vector<school> v; int N,cnt = 0; bool cmp(school a,school b) { if(a.tws!=b.tws) { return a.tws>b.tws; }else if(a.num!=b.num) { return a.num<b.num; }else { return a.name<b.name; } } string stringtosmall(string str) { for(int i=0;i<str.size();i++) { if(str[i]>='A'&&str[i]<='Z') { str[i] = str[i] - 'A' + 'a'; } } return str; } int main() { cin>>N; for(int i=0;i<N;i++) { string id,sch; int score; cin>>id>>score>>sch; sch = stringtosmall(sch); if(mp.find(sch)==mp.end()) { mp[sch] = cnt++; temp.name = sch; temp.num = 1; if(id[0]=='A') { temp.tws = A(score); }else if(id[0]=='B') { temp.tws = B(score); }else if(id[0]=='T') { temp.tws = T(score); } v.push_back(temp); }else { int u = mp[sch]; v[u].num ++; if(id[0]=='A') { v[u].tws += A(score); }else if(id[0]=='B') { v[u].tws += B(score); }else if(id[0]=='T') { v[u].tws += T(score); } } } sort(v.begin(),v.end(),cmp); printf("%d\n",cnt); int score = -1,rank = 0; for(int i=0;i<cnt;i++) { if((v[i].tws/6)==score) { cout<<rank<<" "<<v[i].name<<" "<<v[i].tws/6<<" "<<v[i].num<<endl; }else { cout<<i+1<<" "<<v[i].name<<" "<<v[i].tws/6<<" "<<v[i].num<<endl; score = v[i].tws/6; rank = i+1; } } return 0; }反思:这题很麻烦,tws是一个整数,是最后总分的一个整数。所以推荐应该用三个量来存,存三类考生的总分,最后再来算TWS比较好。还有字符串的处理要熟悉。