PAT (Basic Level) Practice (中文)1085 PAT单位排行(C语言)


思路 

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;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dragon_dd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值