1 #include <iostream> 2 #include <algorithm> 3 using namespace std; 4 struct node//定义国家结构体 5 { 6 int order; 7 double gold, mdl, ppl; 8 int rank[5]; 9 }con[300]; 10 //4个比较函数 11 bool cmp1(node a, node b) 12 { 13 return a.gold > b.gold; 14 } 15 bool cmp2(node a, node b) 16 { 17 return a.mdl > b.mdl; 18 } 19 bool cmp3(node a, node b) 20 { 21 return a.gold / a.ppl > b.gold / b.ppl; 22 } 23 bool cmp4(node a, node b) 24 { 25 return a.mdl / a.ppl > b.mdl / b.ppl; 26 } 27 int main() 28 { 29 int N, M; 30 cin >> N >> M; 31 for (int i = 0; i < N; i++) 32 { 33 con[i].order = i; 34 cin >> con[i].gold >> con[i].mdl >> con[i].ppl; 35 } 36 struct node con2[300];//将con拷贝一份到con2,con保持不动,用con2来排序 37 for (int i = 0; i < N; i++) 38 { 39 con2[i].order = con[i].order; 40 con2[i].gold = con[i].gold; 41 con2[i].mdl = con[i].mdl; 42 con2[i].ppl = con[i].ppl; 43 } 44 int cst[300];//存放要咨询的国家编号 45 for (int i = 0; i < M; i++) 46 { 47 cin >> cst[i]; 48 } 49 int front[300];//front存放前驱结点,用于处理并列名次的情况,相同名次的国家有相同“根节点”,它们的排名就是它们根节点的排名 50 sort(con2, con2 + N, cmp1); 51 for (int i = 0; i < N; i++) front[i] = i;//处理前需要将front初始化 52 for (int i = 0; i < N; i++) 53 { 54 int k;//k为排名对应的下标,真实排名是k+1 55 if (i == 0 || con2[i].gold != con2[i - 1].gold)k = i;//如果没有并列的情况,名次就是i+1 56 else 57 { 58 front[i] = front[i - 1]; 59 k = i; 60 while (k != front[k])//注意这里while循环用意是处理并列排名的情况 61 { 62 k = front[k]; 63 } 64 //while处理完后k的值是多个并列数据中排在最前面的那个的下标,即这一组并列数据的排名都是此时的k值再+1 65 } 66 con[con2[i].order].rank[1] = k + 1; 67 }//以下都是类似的方法 68 sort(con2, con2 + N, cmp2); 69 for (int i = 0; i < N; i++) front[i] = i; 70 for (int i = 0; i < N; i++) 71 { 72 int k; 73 if (i == 0 || con2[i].mdl != con2[i - 1].mdl)k = i; 74 else 75 { 76 front[i] = front[i - 1]; 77 k = i; 78 while (k != front[k]) 79 { 80 k = front[k]; 81 } 82 } 83 con[con2[i].order].rank[2] = k + 1; 84 } 85 sort(con2, con2 + N, cmp3); 86 for (int i = 0; i < N; i++) front[i] = i; 87 for (int i = 0; i < N; i++) 88 { 89 int k; 90 if (i == 0 || con2[i].gold / con2[i].ppl != con2[i - 1].gold / con2[i - 1].ppl)k = i; 91 else 92 { 93 front[i] = front[i - 1]; 94 k = i; 95 while (k != front[k]) 96 { 97 k = front[k]; 98 } 99 } 100 con[con2[i].order].rank[3] = k + 1; 101 } 102 sort(con2, con2 + N, cmp4); 103 for (int i = 0; i < N; i++) front[i] = i; 104 for (int i = 0; i < N; i++) 105 { 106 int k; 107 if (i == 0 || con2[i].mdl / con2[i].ppl != con2[i - 1].mdl / con2[i - 1].ppl)k = i; 108 else 109 { 110 front[i] = front[i - 1]; 111 k = i; 112 while (k != front[k]) 113 { 114 k = front[k]; 115 } 116 } 117 con[con2[i].order].rank[4] = k + 1; 118 } 119 120 for (int i = 0; i < M; i++) 121 { 122 int order = cst[i];//题目说当多个计算方式排名相同时,输出最小编号的方式,这里利用<和<=可实现这一目的。 123 if (con[order].rank[1] <= con[order].rank[2] && con[order].rank[1] <= con[order].rank[3] && con[order].rank[1] <= con[order].rank[4]) 124 cout << con[order].rank[1] << ":1"; 125 else if (con[order].rank[2] < con[order].rank[1] && con[order].rank[2] <= con[order].rank[3] && con[order].rank[2] <= con[order].rank[4]) 126 cout << con[order].rank[2] << ":2"; 127 else if (con[order].rank[3] < con[order].rank[1] && con[order].rank[3] < con[order].rank[2] && con[order].rank[3] <= con[order].rank[4]) 128 cout << con[order].rank[3] << ":3"; 129 else if (con[order].rank[4] < con[order].rank[1] && con[order].rank[4] < con[order].rank[2] && con[order].rank[4] < con[order].rank[3]) 130 cout << con[order].rank[4] << ":4"; 131 if (i != M - 1)cout << ' '; 132 } 133 return 0; 134 135 }