HDU-3789-奥运排序问题

题目传送门 :http://acm.hdu.edu.cn/showproblem.php?pid=3789

题意:

  给国家的奖牌榜排名,有四钟排序方式:排序有4种方式: 金牌总数 奖牌总数 金牌人口比例 奖牌人口比例 。输出要求排序国家的最佳排名,比如a国家的四种排名方式的结果是:1 2 3 4,那么应该输出1:1,表示用的是第一种排序,名次为1。还有几是并列排名问题,如果出现金牌总数为 100,90,90,80.则排名为1,2,2,4。题目种并不是要让你对所以的国家进行排序,他会给出让你排序的国家号,只需对这些国家进行排序即可,刚开始就是这里没理解好wa了好几次,我们只需要把这些需要排序的国家号用数组存起来就可以了!

 

解决方法:

  我是用了sort排序方式,其实不用这么麻烦,直接在输入那里记录最佳排名都可以了。不过个人觉得这样可能会更清晰整个架构,也可以学到sort的一些排序方式控制。首先我是定义了四个cmp函数,用于四种不同的排序方式。用了个结构体来存储国家的信息:
struct mode {
    int
ms; //金牌
    int
cn;  //奖牌
    double
peo;  //人口
    int
index;   //国号
};


每次排序时更新其最佳排名即可。记得要用一个数组来存储要排序的国号,最后我是按照国号来输出其最佳排名的。在每一次输入需要排序的国号时就把他移存到另一个mode数组,用于排序他们。开了个数组K是用来记录其最佳排名的。细节看代码!

 

 

View Code
  1 #include<iostream>
  2 #include<vector>
  3 #include<algorithm>
  4 using namespace std;
  5 
  6 const int maxn = 100000;
  7 int n, m;
  8 
  9 struct mode {
 10     int ms;
 11     int cn;
 12     double peo;
 13     int index;
 14 };
 15 
 16 //按金牌总数
 17 bool cmp1(mode &a, mode &b) {
 18     return a.ms>b.ms;
 19 }
 20 //按奖牌总数
 21 bool cmp2(mode &a, mode &b) {
 22     return a.cn>b.cn;
 23 }
 24 //按金牌人口比例
 25 bool cmp3(mode &a, mode &b) {
 26     return a.ms/a.peo > b.ms/b.peo;
 27 }
 28 //按奖牌人口比例
 29 bool cmp4(mode &a, mode &b) {
 30     return a.cn/a.peo > b.cn/b.peo;
 31 }
 32 
 33 mode V[maxn];
 34 mode V1[maxn];
 35 int K[maxn][2];
 36 int M[maxn];
 37 
 38 void px() {
 39     int i;
 40     //按金牌
 41     sort(V, V+m, cmp1);
 42 
 43     M[0] = 1;
 44 
 45     K[V[0].index][0] = 1;
 46     K[V[0].index][1] = 1;
 47     for(i=1; i<m; i++) {
 48         M[i] = i+1;
 49 
 50         if(V[i-1].ms == V[i].ms) {//如果碰到与前一个国家的排序依据相等就拥有相同的名次
 51         
 52             M[i] = M[i-1];
 53         }
 54         K[V[i].index][0] = M[i];
 55         K[V[i].index][1] = 1;
 56     }
 57     //按奖牌
 58     sort(V, V+m, cmp2);
 59 
 60     M[0] = 1;
 61 
 62     if(K[V[0].index][0]>1) {//如果原来的排名不够现在的佳即更改为现在的名次
 63         K[V[0].index][0] = 1;
 64         K[V[0].index][1] = 2;
 65     }
 66     for(i=1; i<m; i++) {
 67         M[i] = i+1;
 68 
 69         if(V[i-1].cn == V[i].cn) {
 70             M[i] = M[i-1];
 71         }
 72         if(K[V[i].index][0] > M[i]) {
 73             K[V[i].index][0] = M[i];
 74             K[V[i].index][1] = 2;
 75         }
 76     }
 77     //按金牌人口比例
 78     sort(V, V+m, cmp3);
 79 
 80     M[0] = 1;
 81 
 82     if(K[V[0].index][0]>1) {
 83         K[V[0].index][0] = 1;
 84         K[V[0].index][1] = 3;
 85     }
 86     for(i=1; i<m; i++) {
 87         M[i] = i+1;
 88     
 89         if(V[i-1].ms/V[i-1].peo == V[i].ms/V[i].peo) {
 90             M[i] = M[i-1];
 91         }
 92         if(K[V[i].index][0] > M[i]) {
 93             K[V[i].index][0] = M[i];
 94             K[V[i].index][1] = 3;
 95         }
 96     }
 97     //按奖牌人口比例
 98     sort(V, V+m, cmp4);
 99 
100     M[0] = 1;
101 
102     if(K[V[0].index][0]>1) {
103         K[V[0].index][0] = 1;
104         K[V[0].index][1] = 4;
105     }
106     for(i=1; i<m; i++) {
107         M[i] = i+1;
108     
109         if(V[i-1].cn/V[i-1].peo == V[i].cn/V[i].peo) { //如果碰到与前一个国家的排序依据相等就拥有相同的名次
110             M[i] = M[i-1];
111         }
112         
113         if(K[V[i].index][0] > M[i]) { //如果原来的排名不够现在的佳即更改为现在的名次    
114             K[V[i].index][0] = M[i];
115             K[V[i].index][1] = 4;
116         }
117     }
118 }
119 
120 
121 int main() {
122     int i, j;
123     int a, b, c;
124     int flag[maxn];
125     while(cin>>n>>m) {
126         for(i=0; i<n; i++) {
127             scanf("%d%d%lf", &V1[i].ms, &V1[i].cn, &V1[i].peo);
128             V1[i].index = i;
129         }
130         
131         for(i=0; i<m; i++) {
132             scanf("%d", &a);
133             V[i].ms = V1[a].ms;
134             V[i].cn = V1[a].cn;
135             V[i].peo = V1[a].peo;
136             V[i].index = V1[a].index;        
137             flag[i] = a;  //用一个数组记录下要排序的国号,初始时一直错就是只使用了index来记录国号,
138                           //但是最后输出时是用i来做下标,所以碰巧sample可以有重合的结果导致误导。
139         }
140 
141         px();
142 
143         for(i=0; i<m; i++) {
144             printf("%d:%d\n",K[flag[i]][0], K[flag[i]][1]);  //按国号来输出排名
145         }
146         printf("\n");
147     }
148     return 0;
149 }

 

 

 

转载于:https://www.cnblogs.com/ruihua852/archive/2012/09/09/2677318.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值