问题描述
用c语言编写软件完成以下任务:一批选手参加比赛,比赛的规则是最后得分越高,名次越低。当半决赛结束时,要在现场按照选手的出场顺序宣布最后得分和最后名次,获得相同分数的选手具有相同的名次,名次连续编号,不用考虑同名次的选手人数。例如:
选手序号: 1,2,3,4,5,6,7
选手得分: 5,3,4,7,3,5,6
输出名次为:3,1,2,5,1,3,4
问题分析
首先题目要求按照选手的出场顺序(即选手的序号)宣布最后得分,也就是说并不是按照名次的前后顺序输出选手信息,而是按照选手的序号输出最后的得分和名次。
其次,题目要求获得相同分数的选手具有相同的名次,并且名次连续编号,不用考虑同名次的选手人数,因此不存在并列名次占位的情况,也就是说如果存在并列第一,那么下一名的名次是第二名,而不是第三名。
另外,如果只是简单地对选手的得分序列进行排序,那么选手的 得分与选手的序号就不能构成一一对应的关系,那么这样的排序也就没有意义了。出于这几点考虑,此问题并非只使用简单的排序运算就可以解决的。
程序设计
使用结构体来解决该问题。将每个选手的信息(包括序号、得分、名次)存放在一个结构体变量中,然后组成一个结构体数组。
最开始每个结构体变量中只存放选手的序号和得分的信息,然后以选手的得分为比较对象,从小到大进行排序。算法描述如下:
#include<stdio.h>
void score_sort(struct player *num1,int n);
void num_sort(struct player *num1,int n);
void print_rand(struct player *num1,int n);
void set_rand(struct player *num1,int n);
struct player{
int num;
int score;
int rand;
};
int main(){
struct player num1[7]={1,5,0,2,3,0,3,4,0,4,7,0,5,3,0,6,5,0,7,6,0};
print_rand(num1,7);
return 0;
}
void score_sort(struct player *num1,int n){
int i;
int j;
struct player temp;
for(i=0;i<n-1;i++)
for(j=0;j<n-1-i;j++){
if(num1[j].score>num1[j+1].score)
{
temp = num1[j];
num1[j] = num1[j+1];
num1[j+1] = temp;
}
}
}
void num_sort(struct player *num1,int n){
int i;
int j;
struct player temp;
for(i=0;i<n-1;i++)
for(j=0;j<n-1-i;j++){
if(num1[j].num>num1[j+1].num)
{
temp = num1[j];
num1[j] = num1[j+1];
num1[j+1] = temp;
}
}
}
void set_rand(struct player *num1,int n){
int i;
int count=2;
num1[0].rand=1;
for(i=1;i<n;i++)
if(num1[i].score==num1[i-1].score) num1[i].rand=num1[i-1].rand;
else num1[i].rand = count++ ;
}
void print_rand(struct player *num1,int n){
int i;
set_rand(num1,n);
num_sort(num1,n);
printf("num\tscore\trand\n");
for(i=0;i<n;i++){
printf("%3d\t%3d\t%3d\n",num1[i].num,num1[i].score,num1[i].rand);
}
}