C语言选美比赛
问题描述
用c语言编写软件完成以下任务:一批选手参加比赛,比赛的规则是最后得分越高,名次越低。当半决赛结束时,要在现场按照选手的出场顺序宣布最后得分和最后名次,获得相同分数的选手具有相同的名次,名次连续编号,不用考虑同名次的选手人数。例如:选手序号: 1,2,3,4,5,6,7
选手得分: 5,3,4,7,3,5,6
输出名次为:3,1,2,5,1,3,4
问题分析
首先题目要求按照选手的出场顺序(即选手的序号)宣布最后得分,也就是说并不是按照名次的前后顺序输出选手信息,而是按照选手的序号输出最后的得分和名次。其次,题目要求获得相同分数的选手具有相同的名次,并且名次连续编号,不用考虑同名次的选手人数,因此不存在并列名次占位的情况,也就是说如果存在并列第一,那么下一名的名次是第二名,而不是第三名。
另外,如果只是简单地对选手的得分序列进行排序,那么选手的 得分与选手的序号就不能构成一一对应的关系,那么这样的排序也就没有意义了。出于这几点考虑,此问题并非只使用简单的排序运算就可以解决的。
程序设计
使用结构体来解决该问题。将每个选手的信息(包括序号、得分、名次)存放在一个结构体变量中,然后组成一个结构体数组。最开始每个结构体变量中只存放选手的序号和得分的信息,然后以选手的得分为比较对象,从小到大进行排序。算法描述如下:
void sortScore(struct player psn[], int n) { int i, j; struct player tmp; for(i=0; i<n-1; i++) for(j=0; j<n-1-i; j++) { if(psn[j].score>psn[j+1].score) { tmp = psn[j]; psn[j] = psn[j+1]; psn[j+1] = tmp; } } }上面算法中使用了冒泡排序法,对含有n个元素的结构体数组psn中的元素按照score从小到大的顺序进行排序。排序后的数组psn按照score的值从小到大排列。
接着指定每一位选手的名次。因为此时结构体数组psn已按照score从小到大排列了,因此就比较容易设定每一位选手的名次了。使用算法描述如下:
void setRand(struct player psn[], int n) { int i,j=2; psn[0].rand=1; for(i=1; i<n; i++) { if(psn[i].score!=psn[i-1].score ) { psn[i].rand=j; j++; } else psn[i].rand=psn[i-1].rand; } }首先给第一位选手psn[0]的名次设定为1,因为它的得分是最少的。然后依次给psn[2]〜psn[n-1]设定名次。如果psn[i].score不等于psn[i-1].score,说明psn[i]的名次要落后一名;否则psn[i]的名次与psn[i-1]的名次相同。
最后再按照选手的序号重新排序,以便能够按照选手的序号输出结果。该算法描述如下:
void sortNum(struct player psn[], int n) { int i,j; struct player tmp; for(i=0; i<n-1; i++) for(j=0; j<n-1-i; j++) { if(psn[j].num>psn[j+1].num) { tmp = psn[j]; psn[j] = psn[j+1]; psn[j+1] = tmp; } } }
下面是完整的代码:
#include <stdio.h> struct player{ int num; int score; int rand; }; void sortScore(struct player psn[], int n) { int i, j; struct player tmp; for(i=0; i<n-1; i++) for(j=0; j<n-1-i; j++) { if(psn[j].score>psn[j+1].score) { tmp = psn[j]; psn[j] = psn[j+1]; psn[j+1] = tmp; } } } void setRand(struct player psn[], int n) { int i,j=2; psn[0].rand=1; for(i=1; i<n; i++) { if(psn[i].score!=psn[i-1].score ) { psn[i].rand=j; j++; } else psn[i].rand=psn[i-1].rand; } } void sortNum(struct player psn[], int n) { int i,j; struct player tmp; for(i=0; i<n-1; i++) for(j=0; j<n-1-i; j++) { if(psn[j].num>psn[j+1].num) { tmp = psn[j]; psn[j] = psn[j+1]; psn[j+1] = tmp; } } } void sortRand(struct player psn[], int n) { sortScore(psn,n); /*以分数为关键字排序*/ setRand(psn,n); /*按照分数排名次*/ sortNum(psn,n); /*按照序号重新排序*/ } int main() { struct player psn[7]={{1, 5, 0}, {2, 3, 0}, {3, 4, 0}, {4, 7, 0}, {5, 3, 0}, {6, 5, 0}, {7, 6, 0}}; int i; sortRand(psn, 7); printf("num score rand \n"); for(i=0; i<7; i++) { printf("%d%6d%6d\n", psn[i].num, psn[i].score, psn[i].rand); } getche(); return 0; }运行结果:
num score rand
1 5 3
2 3 1
3 4 2
4 7 5
5 3 1
6 5 3
7 6 4