目的:根据学生的表现,生成机构的排名
输入:
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比较好。还有字符串的处理要熟悉。