题目传送门 :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是用来记录其最佳排名的。细节看代码!
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 }