7-41 PAT排名汇总

快速排序与成绩排名实现
本文详细介绍了一种基于快速排序算法的学生考试成绩排名系统。该系统首先通过局部快速排序为不同考点的学生进行初步排名,然后使用全局快速排序完成所有学生的最终排名。文章深入解析了快速排序算法的实现细节,包括分区函数、比较函数的设计,以及如何处理相同分数情况下的排名逻辑。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct Student {
    char no[14];
    int grade;
    int test_loc;
    int init_rank;
    int final_rank;
} Stu;
Stu stu[30000];
int partition(int left,int right) {
    int i=left,j=right,pivot=stu[left].grade;
    Stu temp=stu[left];
    while(i<j) {
        while(i<j && stu[j].grade<=pivot) j--;
        stu[i]=stu[j];
        while(i<j && stu[i].grade>=pivot) i++;
        stu[j]=stu[i];
    }
    stu[i]=temp;
    return i;
}
void partQuickSort(int left,int right) {//局部快排用于考点排名 
    if(left>=right) return;
    int pivot=partition(left,right);
    partQuickSort(left,pivot-1);
    partQuickSort(pivot+1,right);
}
int cmp(const void * a,const void *b) {//用于全部考生成绩排序的快排比较函数 
    Stu *sa = (Stu *)a;
    Stu *sb = (Stu *)b;
    if(sa->grade!=sb->grade) {
        return sb->grade-sa->grade;
    } else {
        return strcmp(sa->no,sb->no);
    }
}
int main() {
    int n,cnt,num=0,begin,locate=0,flag=1,rank=1;
    scanf("%d",&n);
    for(int i=0; i<n; i++) {
        scanf("%d",&cnt);
        locate++;
        begin=num;
        for(int j=0; j<cnt; j++) {
            scanf("%s %d",stu[num].no,&stu[num].grade);
            stu[num].test_loc=locate;
            num++;
        }
        //考点排序
        partQuickSort(begin,num-1);
        //考点排名
        rank=1;
        flag=1;
        for(int k=begin; k<num; k++) {
            if(flag) {
                stu[k].init_rank=1;
                flag=0;
                rank++;
            } else {
                if(stu[k].grade==stu[k-1].grade) {
                    stu[k].init_rank=stu[k-1].init_rank;
                    rank++;
                } else {
                    stu[k].init_rank=rank;
                    rank++;
                }
            }
        }
    }
    //最终排序
    qsort(stu,num,sizeof(stu[0]),cmp) ;
    //最终排名
    rank=1;
    flag=1;
    for(int k=0; k<num; k++) {
        if(flag) {
            stu[k].final_rank=1;
            flag=0;
            rank++;
        } else {
            if(stu[k].grade==stu[k-1].grade) {
                stu[k].final_rank=stu[k-1].final_rank;
                rank++;
            } else {
                stu[k].final_rank=rank;
                rank++;
            }
        }
    }
    //output
    printf("%d\n",num);
    for(int i=0; i<num; i++) {
        printf("%s %d %d %d\n",stu[i].no,stu[i].final_rank,stu[i].test_loc,stu[i].init_rank);
    }
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值