http://ac.jobdu.com/problem.php?pid=1007

题目描述:

按要求,给国家进行排名。

输入:
有多组数据。
第一行给出国家数N,要求排名的国家数M,国家号从0到N-1。
第二行开始的N行给定国家或地区的奥运金牌数,奖牌数,人口数(百万)。
接下来一行给出M个国家号。
输出:
排序有4种方式: 金牌总数 奖牌总数 金牌人口比例 奖牌人口比例 
对每个国家给出最佳排名排名方式 和 最终排名
格式为: 排名:排名方式
如果有相同的最终排名,则输出排名方式最小的那种排名,对于排名方式,金牌总数 < 奖牌总数 < 金牌人口比例 < 奖牌人口比例 
如果有并列排名的情况,即如果出现金牌总数为 100,90,90,80.则排名为1,2,2,4.
每组数据后加一个空行。
样例输入:
4 4
4 8 1
6 6 2
4 8 2
2 12 4
0 1 2 3
4 2
8 10 1
8 11 2
8 12 3
8 13 4
0 3
样例输出:
1:3
1:1
2:1
1:2

1:1
1:1

尼玛呀,不要对所有国家进行排序,只要那M个国家。排序之后原序号就乱了。然后,很弱智的问题,排序后跟前一个国家比较相等后,并不是取前一个国家的最好排名,而是这次排名。写代码的时候会短路啊。看代码更短路啊!

[cpp]  view plain copy
  1. #include <iostream>  
  2. #include <string>  
  3. #include <algorithm>  
  4. #include <memory.h>  
  5. #include <cstdio>  
  6. #include <cstdlib>  
  7.   
  8. using namespace std;  
  9. int way;  
  10. struct Node{  
  11.     int praise;  
  12.     int gold;  
  13.     int people;  
  14.     double goldrate;  
  15.     double praiserate;  
  16.     int min;  
  17.     int way;  
  18.     int th;  
  19.       
  20. };  
  21. double getvalue(const Node & node){  
  22.     switch(way){  
  23.         case 1:return node.gold;  
  24.         case 2:return node.praise;  
  25.         case 3:return node.goldrate;  
  26.         case 4:return node.praiserate;  
  27.         case 5:return -node.th;  
  28.     }  
  29. }  
  30. int cmp(const Node &a, const Node &b){  
  31.     return getvalue(a)>getvalue(b);  
  32. }  
  33. Node nodes[100];;  
  34. Node src[100];  
  35. int main(){  
  36.   
  37.     //freopen("in.txt", "r", stdin);  
  38.     int n, m, t;  
  39.     while(cin>>n>>m){  
  40.         for(int i=0;i<n;++i){  
  41.             scanf("%d%d%d", &src[i].gold, &src[i].praise, &src[i].people);  
  42.             src[i].goldrate = (src[i].gold+0.0)/src[i].people;  
  43.             src[i].praiserate = (src[i].praise+0.0)/src[i].people;  
  44.         }  
  45.         for(int i=0;i<m;++i){  
  46.             scanf("%d", &t);  
  47.             nodes[i] = src[t];    
  48.             nodes[i].th = i;  
  49.         }  
  50.   
  51.         way = 1;  
  52.         sort(nodes, nodes+m, cmp);  
  53.         nodes[0].min = 1;  
  54.         nodes[0].way = 1;  
  55.         for(int i=1;i<n;++i){  
  56.             if(getvalue(nodes[i])==getvalue(nodes[i-1]))  
  57.                 nodes[i].min = nodes[i-1].min;  
  58.             else  
  59.                 nodes[i].min = i+1;  
  60.             nodes[i].way = 1;  
  61.         }  
  62.         for(way=2;way<=4;++way){  
  63.             sort(nodes, nodes+m, cmp);  
  64.             if(nodes[0].min!=1){  
  65.                 nodes[0].min = 1;  
  66.                 nodes[0].way = way;  
  67.             }  
  68.             int pre = 1;  
  69.             for(int i=1;i<n;++i){  
  70.                 int th;  
  71.                 if(getvalue(nodes[i])==getvalue(nodes[i-1])){  
  72.                     th = pre;//跟之前的国家的这次排名相等,not nodes[i].min  
  73.                 }else{  
  74.                     th = i+1;  
  75.                     pre = th;  
  76.                 }  
  77.                 if(th<nodes[i].min){  
  78.                     nodes[i].min = th;  
  79.                     nodes[i].way = way;  
  80.                 }  
  81.               
  82.             }  
  83.         }  
  84.         way = 5;  
  85.         sort(nodes, nodes+m, cmp);  
  86.         for(int i=0;i<m;++i){  
  87.             printf("%d:%d\n", nodes[i].min, nodes[i].way);  
  88.         }  
  89.         printf("\n");  
  90.   
  91.     }  
  92.     //fclose(stdin);  
  93. }     
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值