HZNU1684——奖学金

传送门
目录
题意:
题解:
C语言快速排序版
C语言冒泡排序版
C++版
题意: 单组输入,给出n个学生的语数外的分数,要求按照一定排名规则排序之后输出前五位同学的学号和总分。
排名规则:先按总分从高到低排序,如果两个同学总分相同,再按语文成绩从高到低排序,如果两个同学总分和语文成绩都相同,那么规定学号小的同学 排在前面。
学号:每个学生的学号按照输入顺序编号为l~n (恰好是输入数据的行号减1)。!输入数据中不含学号,需要我们手动添加。
题解: 定义一个结构体,包含学生的学号、语数外成绩以及总分等数据;通过c++的排序函数sort给结构体排序,按顺序输出前五位同学的信息即可。

  • 结构体的定义:struct 啥啥{int 什么}某某;
struct student{ int xh, yw, sx, yy, zf; }s[310]; //学号、语文、数学、英语、总分

C语言快速排序版
  • 比较函数:int 啥(const void *甲, const void *乙){比较规则;}
int cmp(const void *A,const void *B) { struct student *a = (struct student*)A; struct student *b = (struct student*)B; if(a->zf == b->zf){ if(a->yw == b->yw) return a->xh - b->xh; //前者-后者表示从小大大排序 return b->yw - a->yw; } return b->zf - a->zf; }

  • 快速排序:qsort(数组名,数组长度,sizeof(数组),比较函数);
qsort(s+1, n, sizeof(struct student), cmp);

难点在于qsort的使用,以及比较函数的定义。
#include #includestruct student{ int xh, yw, sx, yy, zf; }s[310]; //学号、语文、数学、英语、总分 int cmp(const void *A,const void *B) { struct student *a = (struct student*)A; struct student *b = (struct student*)B; if(a->zf == b->zf){ if(a->yw == b->yw) return a->xh - b->xh; return b->yw - a->yw; } return b->zf - a->zf; }int n; int main(){ scanf("%d", &n); for(int i=1; i<=n; i++){ scanf("%d%d%d", &s[i].yw, &s[i].sx, &s[i].yy); s[i].xh = i; //数据输入是按学号顺序的,数据中不显示学号,需要我们手动添加 s[i].zf = s[i].yw + s[i].sx + s[i].yy; //计算总分 } qsort(s+1, n, sizeof(struct student), cmp); for(int i=1; i<6; i++) printf("%d %d\n", s[i].xh, s[i].zf); return 0; }

C语言冒泡排序版
  • 冒泡排序:运用双重循环给结构体排序,效率低下。
for(int i=n; i>=1; i--){ for(int j=1; j s[j+1].xh) //执行交换 } } }

  • 交换函数Swap
void Swap(struct student *a, struct student *b){ struct student c = *a; *a = *b; *b = c; }

  • 整体代码与另外两者均雷同,不再赘述
#include #includestruct student{ int xh, yw, sx, yy, zf; }s[310]; //学号、语文、数学、英语、总分 void Swap(struct student *a, struct student *b){ struct student c = *a; *a = *b; *b = c; }int main(){ // freopen("text.in", "r", stdin); int n; scanf("%d", &n); for(int i=1; i<=n; i++){ scanf("%d%d%d", &s[i].yw, &s[i].sx, &s[i].yy); s[i].xh = i; //数据输入是按学号顺序的,数据中不显示学号,需要我们手动添加 s[i].zf = s[i].yw + s[i].sx + s[i].yy; //计算总分 } for(int i=n; i>=1; i--){ for(int j=1; j s[j+1].xh) Swap(&s[j], &s[j+1]); } } } for(int i=1; i<6; i++) printf("%d %d\n", s[i].xh, s[i].zf); return 0; }


C++版
  • 排序规则函数:bool 啥(甲, 乙){排序规则;}。虽然排序要求多,但是函数并不难写。
bool cmp(student &a, student &b) { if(a.zf == b.zf){ if(a.yw == b.yw) return a.xh < b.xh; return a.yw > b.yw; } return a.zf > b.zf; }

  • 排序函数:sort(数组起始,数组终止,排序规则);
sort(s+1, s+n+1, cmp);

对于C++可能相对陌生的就是排序规则cmp和排序函数sort(),整体的代码比较简单,看其中文字注释即可。
#include #include using namespace std; struct student{ int xh, yw, sx, yy, zf; }s[310]; //学号、语文、数学、英语、总分 bool cmp(student &a, student &b) { if(a.zf == b.zf){ if(a.yw == b.yw) return a.xh < b.xh; return a.yw > b.yw; } return a.zf > b.zf; }int n; int main(){ scanf("%d", &n); for(int i=1; i<=n; i++){ scanf("%d%d%d", &s[i].yw, &s[i].sx, &s[i].yy); s[i].xh = i; //数据输入是按学号顺序的,数据中不显示学号,需要我们手动添加 s[i].zf = s[i].yw + s[i].sx + s[i].yy; //计算总分 } sort(s+1, s+n+1, cmp); //sort是c++里的一个排序函数,参数分别是数组的起始、终止位置以及一个排序规则函数 for(int i=1; i<6; i++) printf("%d %d\n", s[i].xh, s[i].zf); return 0; }

【HZNU1684——奖学金】

    推荐阅读