| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1047 人关注过本帖
标题:c语言趣题之“选美比赛”
只看楼主 加入收藏
巧若拙
Rank: 4
来 自:宁波余姚
等 级:业余侠客
威 望:1
帖 子:159
专家分:273
注 册:2014-8-24
结帖率:46.15%
收藏
已结贴  问题点数:2 回复次数:5 
c语言趣题之“选美比赛”
程序代码:
/*
在选美大奖赛的半决赛现场,有一批选手参加比赛,比赛的规则是最后的得分越高,名次越低。
当半决赛结束时,要在现场按照选手的出场顺序宣布最后得分和最后名次,获得相同分数的选手具有相同的名次,
名次连续编号,不要考虑同名次的选手人数。例如:
选手序号:1,2,3,4,5,6,7
选手得分:5,3,4,7,3,5,6
则输出名次为:3,1,2,5,1,3,4
请编程帮助大奖赛组委会完成半决赛的评分排名工作。

函数接口:void ScorePlace(int place[], const int score[], int num);
输入:存储选手名次的数组place[],存储选手得分的数组score[],选手人数num。
输出:存储选手名次的数组place[]。

示例1:
输入:score[] = {2,8,5,1,10,5,9,9};
输出:place[] = {2,4,3,1, 6,3,5,5};
示例2:
输入:score[] = {7,7,6,6,7};
输出:place[] = {2,2,1,1,2};
*/

#include <time.h>
#include<stdio.h>
#include<stdlib.h>

#define MAX 20000 

typedef struct Player {
    int rank; //排名
    int sco; //成绩 
} Player;

int Cmp(const void *a , const void *b); 
void ScorePlace(int place[], const int score[], int num);
void ScorePlace_c(int place[], const int score[], int num);

int main()
{
    int score[MAX] = {0};
    int place1[MAX] = {0};
    int place2[MAX] = {0};
    int sum = 0;
    int i, k, max;

   // max = rand()%(MAX-10) + 10;
   
    max = MAX;
    for (i=0; i<max; i++)
           score[i] = rand()%101 + 1;

    ScorePlace_1(place1, score, max);
    printf("p[%d] = %d\n", max-1, place1[max-1]);
    
    ScorePlace_2(place2, score, max);
    printf("p[%d] = %d\n", max-1, place2[max-1]);

    return 0;
}

void ScorePlace_1(int place[], const int score[], int num)
{
    int *sameScore;
    int i, j, k, numPlace = 1;  //选手的名次
      
    sameScore = (int *)malloc(sizeof(int) * num);
    if (!sameScore)
    {
        puts("Error"); 
        exit(1);
    }

      for (i=0; i<num; i++)//为每个选手的名次设初值为0,表示还未对其排名
            place[i] = 0;

      for (i=0; i<num; i++)//遍历数组,每次处理一个名次
      {
            if (place[i] == 0)//如果还未对该元素进行排名
            {
                  int min = score[i]; //取该元素作为当前最小值
                  int same = 0;
                  sameScore[same] = i;//记录分值为min的(即具有相同名次)元素的下标

                  for (j=i+1; j<num; j++)//对余下元素进行处理
                  {
                        if (place[j] == 0)
                        {
                              if (score[j] < min)//若该元素比min小,取该元素作为当前最小值
                              {
                                    min = score[j];
                                    same = 0;  //重新记录分值为min的(即具有相同名次)元素的个数
                                    sameScore[same] = j;
                              }
                              else if (score[j] == min)//若该元素等于min,则其属于具有相同名次的元素
                              {
                                    sameScore[++same] = j; //记录分值为min的元素的下标
                              }
                        }
                  }
                  for (k=0; k<=same; k++)//对具有相同名次的元素进行排名
                  {
                        place[sameScore[k]] = numPlace;
                  }

                  numPlace++; //名次增一
                  i = -1; //重新查找下一个尚未排名的元素进行排名处理
            }
      }
      free(sameScore);
}

int Cmp(const void *a , const void *b) 
{ 
    return ((Player *)a)->sco - ((Player *)b)->sco; 
}

void ScorePlace_2(int place[], const int score[], int num)//使用快速排序对结构体数组排序,然后递增名次即可 
{
    int i;
    Player *p;
    
    p = (Player *)malloc(sizeof(Player) * num);
    if (!p)
    {
        puts("Error"); 
        exit(1);
    }
    
    for (i=0; i<num; i++)
    {
        p[i].rank = i;
        p[i].sco = score[i];
    }

    qsort(p, num, sizeof(p[0]), Cmp);
    
    place[p[0].rank] = 1;
    for (i=1; i<num; i++)
    {
        if (p[i].sco == p[i-1].sco)
            place[p[i].rank] = place[p[i-1].rank];    
        else
            place[p[i].rank] = place[p[i-1].rank] + 1;    
    }
    free(p);
}


[ 本帖最后由 巧若拙 于 2014-12-30 15:45 编辑 ]
搜索更多相关主题的帖子: 半决赛 大奖赛 组委会 c语言 接口 
2014-12-30 15:41
wp231957
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:神界
等 级:贵宾
威 望:423
帖 子:13688
专家分:53332
注 册:2012-10-18
收藏
得分:1 
关注

DO IT YOURSELF !
2014-12-30 16:11
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9031
专家分:54061
注 册:2011-1-18
收藏
得分:1 
回复 2楼 wp231957
两次排序(C标准库中有 qsort 函数)就行了
原数组是 { (1,5),(2,3),(3,4),(4,7),(5,3),(6,5),(7,6) } // (前面是序号,后面是得分)
先以得分排序,得到 { (2,3),(5,3),(3,4),(1,5),(6,5),(7,6),(4,7) }
然后将得分换成排名,规则是:排名从1开始,若比前一个大,则排名加一。得到 { (2,1),(5,1),(3,2),(1,3),(6,3),(7,4),(4,5) }
再以序号排序,得 { (1,3),(2,1),(3,2),(4,5),(5,1),(6,3),(7,4) }
输出排名,结束。
2014-12-30 16:39
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:1 
凑个热闹。其实和楼主的第二个算法一样,只不过数据结构不同,交流一下编码心得。

程序代码:
int cmp(const void * a, const void * b)
{
    return ((int *)a)[1] - ((int *)b)[1];
}

void ScorePlace(int place[], const int score[], int num)
{
    int (*s)[2], i, j;

    s = (int (*)[2])malloc(sizeof(s[0]) * num);
    for(i = 0; i < num; i++)
    {
        s[i][0] = i;
        s[i][1] = score[i];
    }

    qsort(s, num, sizeof(s[0]), cmp);

    for(place[s[0][0]] = j = i = 1; i < num; i++)
        place[s[i][0]] = (s[i][1] == s[i - 1][1]) ? j : ++j;

    free(s);
}

重剑无锋,大巧不工
2014-12-30 18:20
巧若拙
Rank: 4
来 自:宁波余姚
等 级:业余侠客
威 望:1
帖 子:159
专家分:273
注 册:2014-8-24
收藏
得分:0 
谢谢楼上的几位,又让我学会了一些qsort函数的用法。
2014-12-30 22:04
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9031
专家分:54061
注 册:2011-1-18
收藏
得分:0 
回复 4楼 beyondyf
谢谢
2014-12-31 08:21
快速回复:c语言趣题之“选美比赛”
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.022908 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved