思路
1、 原打算用bsearch函数的,但是考虑到使用前需要qsort排序,每多一个没有出现过的学校,就得qsort一次,可能会超时,就没有用;
2、那么就全部接收数据,然后先按照学校id排序一次,id相同的就会排在一起,整合起来就比较方便,复杂度不高;
3、使用while循环来重新整合学校数据,id相同的学校,分数全部累加,整合好后再进行加权总分的计算,最后再按照输出的要求再排一次序就ok了。
AC代码
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct{
char id[7];
int b;
int a;
int t;
int s;//加权总分
int c;//考生人数
}school;
int cmp1(const void* a,const void* b){//按学校id排序
school* pa=(school*)a;
school* pb=(school*)b;
return strcmp(pa->id,pb->id);
}
int cmp2(const void* a,const void* b){//按输出要求排序
school* pa=(school*)a;
school* pb=(school*)b;
if(pa->s!=pb->s)return pb->s-pa->s;
else if(pa->s==pb->s&&pa->c!=pb->c)return pa->c-pb->c;
else return strcmp(pa->id,pb->id);
}
void transform(char id[]){//大写转小写
for(int i=0,l=strlen(id);i<l;i++)
if(id[i]>='A'&&id[i]<='Z')id[i]=id[i]-'A'+'a';
}
int main(){
int n,score,c=0;
char p,id[7];
scanf("%d%*c",&n);
school a[n],b[n];
for(int i=0;i<n;i++){
a[i].b=a[i].a=a[i].t=0;//接收数据的同时初始化学校信息
scanf("%c%*s %d %s%*c",&p,&score,a[i].id);
transform(a[i].id);//学校id全部转小写
if(p=='A')a[i].a+=score;//对应总分累加
if(p=='B')a[i].b+=score;
if(p=='T')a[i].t+=score;
}
qsort(a,n,sizeof(school),cmp1);//按学校id排序,使id相同的学校排在一起,方便信息整合
for(int i=0;i<n;i++){
strcpy(b[c].id,a[i].id);
b[c].b=b[c].a=b[c].t=b[c].c=0;
while(strcmp(b[c].id,a[i].id)==0){//学校id相同的整合为一个学校,用b重新整合
b[c].b+=a[i].b;
b[c].a+=a[i].a;
b[c].t+=a[i].t;
b[c].c++;
i++;
}
b[c].s=(float)b[c].b/1.5+b[c].a+(float)b[c].t*1.5;//计算加权总分
c++;//下一整合学校
i--;//因为for循环会自+1,所以先-1
}
qsort(b,c,sizeof(school),cmp2);//按输出要求排序
printf("%d\n",c);
int rank;//rank表学校排名
for(int i=0;i<c;i++){
if(i==0)rank=1;
else{if(b[i].s!=b[i-1].s)rank=i+1;}
printf("%d %s %d %d\n",rank,b[i].id,b[i].s,b[i].c);
}
return 0;
}