96.選美比賽
在選美大獎賽的半決勝賽現(xiàn)場,有一批選手參加比賽,比賽的規(guī)則是最后得分越高,名次越低。當(dāng)半決決賽結(jié)束時,要在現(xiàn)場按照選手的出場順序宣布最后得分和最后名次,獲得相同分?jǐn)?shù)的選手具有相同的名次,名次連續(xù)編號,不用考慮同名次的選手人數(shù)。例如:
選手序號: 1,2,3,4,5,6,7
選手得分: 5,3,4,7,3,5,6
則輸出名次為: 3,1,2,5,1,3,4
請編程幫助大獎賽組委會完成半決賽的評分和排名工作。
*問題分析與算法設(shè)計
問題用程序設(shè)計語言加以表達的話,即為:將數(shù)組A中的整數(shù)從小到大進行連續(xù)編號,要求不改變數(shù)組中元素的順序,且相同的整數(shù)要具有相同的編號。
普通的排序方法均要改變數(shù)組元素原來的順序,顯然不能滿足要求。為此,引入一個專門存放名次的數(shù)組,再采用通常的算法:在尚未排出名次的元素中找出最小值,并對具有相同值的元素進行處理,重復(fù)這一過程,直到全部元素排好為止。
*程序與程序注釋
#include
#define NUM 7 /*定義要處理的人數(shù)*/
int a[NUM+1]={0,5,3,4,7,3,5,6}; /*為簡單直接定義選手的分?jǐn)?shù)*/
int m[NUM+1],l[NUM+1]; /*m:已編名次的標(biāo)記數(shù)組 l:記錄同名次元素的下標(biāo)*/
void main()
{
int i,smallest,num,k,j;
num=1; /*名次*/
for(i=1;i<=NUM;i++) /*控制掃描整個數(shù)組,每次處理一個名次*/
if(m[i]==0) /*若尚未進行名次處理(即找到第一個尚未處理的元素)*/
{
smallest=a[i]; /*取第一個未處理的元素作為當(dāng)前的最小值*/
k=1; /*數(shù)組l的下標(biāo),同名次的人數(shù)*/
l[k]=i; /*記錄分值為smallest的同名次元素的下標(biāo)*/
for(j=i+1;j<=NUM;j++) /*從下一個元素開始對余下的元素進行處理*/
if(m[j]==0) /*若為尚未進行處理的元素*/
if(a[j] {
smallest=a[j]; /*則重新設(shè)置當(dāng)覵最小值*/
k=0; /*重新設(shè)置同名次人數(shù)*/
l[++k]=j; /*重新記錄同名次元素下標(biāo)*/
}
else if(a[j]==smallest) /*若與當(dāng)前最低分相同*/
l[++k]=j; /*記錄同名次的元素下標(biāo)*/
for(j=1;j<=k;j++) /*對同名次的元素進行名次處理*/
m[l[j>=num;
num++; /*名次加1*/
i=0; /*控制重新開始,找下一個沒排名次的元素*/
}
printf("Player-No score Rank\n");
for(j=1;j<=NUM;j++) /*控制輸出*/
printf(" %3d %4d %4d\n",j,a[j],m[j]);
}
*運行結(jié)果
Player-No Score Rank
1 5 3
2 3 1
3 4 2
5 7 5
5 3 1
3 5 3
7 6 4
*思考題
若將原題中的“名次連續(xù)編號,不用考慮同名次的選手人數(shù)”,改為”根據(jù)同名次的選手人數(shù)對選手的名次進行編號“,那么應(yīng)該怎樣修改程序。
在選美大獎賽的半決勝賽現(xiàn)場,有一批選手參加比賽,比賽的規(guī)則是最后得分越高,名次越低。當(dāng)半決決賽結(jié)束時,要在現(xiàn)場按照選手的出場順序宣布最后得分和最后名次,獲得相同分?jǐn)?shù)的選手具有相同的名次,名次連續(xù)編號,不用考慮同名次的選手人數(shù)。例如:
選手序號: 1,2,3,4,5,6,7
選手得分: 5,3,4,7,3,5,6
則輸出名次為: 3,1,2,5,1,3,4
請編程幫助大獎賽組委會完成半決賽的評分和排名工作。
*問題分析與算法設(shè)計
問題用程序設(shè)計語言加以表達的話,即為:將數(shù)組A中的整數(shù)從小到大進行連續(xù)編號,要求不改變數(shù)組中元素的順序,且相同的整數(shù)要具有相同的編號。
普通的排序方法均要改變數(shù)組元素原來的順序,顯然不能滿足要求。為此,引入一個專門存放名次的數(shù)組,再采用通常的算法:在尚未排出名次的元素中找出最小值,并對具有相同值的元素進行處理,重復(fù)這一過程,直到全部元素排好為止。
*程序與程序注釋
#include
#define NUM 7 /*定義要處理的人數(shù)*/
int a[NUM+1]={0,5,3,4,7,3,5,6}; /*為簡單直接定義選手的分?jǐn)?shù)*/
int m[NUM+1],l[NUM+1]; /*m:已編名次的標(biāo)記數(shù)組 l:記錄同名次元素的下標(biāo)*/
void main()
{
int i,smallest,num,k,j;
num=1; /*名次*/
for(i=1;i<=NUM;i++) /*控制掃描整個數(shù)組,每次處理一個名次*/
if(m[i]==0) /*若尚未進行名次處理(即找到第一個尚未處理的元素)*/
{
smallest=a[i]; /*取第一個未處理的元素作為當(dāng)前的最小值*/
k=1; /*數(shù)組l的下標(biāo),同名次的人數(shù)*/
l[k]=i; /*記錄分值為smallest的同名次元素的下標(biāo)*/
for(j=i+1;j<=NUM;j++) /*從下一個元素開始對余下的元素進行處理*/
if(m[j]==0) /*若為尚未進行處理的元素*/
if(a[j]
smallest=a[j]; /*則重新設(shè)置當(dāng)覵最小值*/
k=0; /*重新設(shè)置同名次人數(shù)*/
l[++k]=j; /*重新記錄同名次元素下標(biāo)*/
}
else if(a[j]==smallest) /*若與當(dāng)前最低分相同*/
l[++k]=j; /*記錄同名次的元素下標(biāo)*/
for(j=1;j<=k;j++) /*對同名次的元素進行名次處理*/
m[l[j>=num;
num++; /*名次加1*/
i=0; /*控制重新開始,找下一個沒排名次的元素*/
}
printf("Player-No score Rank\n");
for(j=1;j<=NUM;j++) /*控制輸出*/
printf(" %3d %4d %4d\n",j,a[j],m[j]);
}
*運行結(jié)果
Player-No Score Rank
1 5 3
2 3 1
3 4 2
5 7 5
5 3 1
3 5 3
7 6 4
*思考題
若將原題中的“名次連續(xù)編號,不用考慮同名次的選手人數(shù)”,改為”根據(jù)同名次的選手人數(shù)對選手的名次進行編號“,那么應(yīng)該怎樣修改程序。