介绍一个二次排序的小技巧(best coder27期1001jump jump jump)

先来描述一下问题:

问题描述
n小孩在比赛跳远,看谁跳的最远。每个小孩可以跳3次,这个小孩的成绩就是三次距离里面的最大值。例如,一个小孩跳3次的距离分别时10, 30和20,那么这个小孩的成绩就是30。给出每个孩子三次跳的距离,问最终每个孩子的排名是多少。

问题分析:
方法1:
  由于原问题规模较少,只有两个或三个孩子,可以采用暴力的方法解决,也可满足时间在1s之内(除java代码)。

方法2:
  由于该问题按孩子跳远距离的最大值进行排序的话,再次按孩子照顺序输出的时候就会出现,由于原顺序未保存而导致不正确。

解决方案:
   设计新结构体存储一个孩子的三个结构信息,跳远距离,当前顺序和排序后的优先级。然后分别按照跳远距离排序,然后根据顺序更新优先级,然后再按照最初的输入顺序进行排序。
 
代码如下:
 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 #define MAX_NUM 10
 5 
 6 typedef struct jump_kid
 7 {
 8 int num;
 9 int value;
10 int pri;
11 
12 }jump_kid;
13 
14 int max_of_three(int a,int b,int c)
15 {/*前提a!=b!=c*/
16   int max3;
17   if(a > b && a > c)
18     max3 = a;
19   else if(b > a && b > c)
20     max3 = b;
21   else
22     max3 = c;
23   return max3;
24 }
25 
26 int comp_kids_value(const void *a, const void *b)
27 {//value降序排序
28   return ( ((jump_kid *)b)->value - ((jump_kid *)a)->value );
29 }
30 
31 int comp_kids_num(const void *a, const void *b)
32 {
33   return ( ((jump_kid *)a)->num - ((jump_kid *)b)->num );
34 }
35 int main()
36 {
37   int i,j,num_case,num_kid,jump1,jump2,jump3;
38   jump_kid kids[MAX_NUM];
39   
40   scanf("%d",&num_case);
41 
42   for(i = 1; i <= num_case; i++)
43   {
44     memset(kids,0,sizeof(kids));
45     scanf("%d",&num_kid);
46     for(j = 0; j < num_kid; j++)
47     {
48       scanf("%d%d%d",&jump1,&jump2,&jump3);
49       kids[j].num = j + 1;
50       kids[j].pri = 0;
51       kids[j].value = max_of_three(jump1,jump2,jump3);
52     }
53 
54     qsort(kids,num_kid,sizeof(jump_kid),comp_kids_value); //第一遍按照value值排序
55 
56     for( j = 0; j < num_kid; j++)
57     {
58       kids[j].pri = j + 1; //排序后更新优先级
59     }
60 
61     qsort(kids,num_kid,sizeof(jump_kid),comp_kids_num);
62 
63     for( j = 0; j < num_kid; j++)
64     printf("%d ",kids[j].pri);
65 
66     printf("
");
67   }
68 
69 }
我是一块砖,哪里需要往哪搬。
原文地址:https://www.cnblogs.com/daimadebanyungong/p/4256290.html