C趣味編程百例(32)選美比賽

字號:

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)該怎樣修改程序。