题目类型 简单题
题目意思
输入 n 场赛车比赛的前 m 名的选手的名字 其中只有前10名的选手可以得到分数(1 <= n <= 20, 1 <= m <= 50)
现在有两种排序方法 输出两种排序方法中排在第1的人的名字
方法一 先按 得分排序 得分相同的 按排在第1的次数排序(多的排在前面) 如果次数相同就按排在第2的次数排序 直到比较出来为止
方法二 先按排在第1的次数排序 次数相同的话按得分高低排序 得分相同的按排在第2的次数排序 还是相同的按排在第3的次数排序 直到比较出来为止
解题方法
统计信息然后排序即可
注意
每场比赛只有前10名可以得分 其他名次得0分但是依然可以得到 相应的名次的次数 (注意数组越界什么的)
参考代码 - 有疑问的地方在下方留言 看到会尽快回复的
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <algorithm>
#include <vector>
#include <string>using namespace std;typedef long long LL;const int MAXN = 1e3 + 10;struct P {string name;int s;int w;vector<int>rank;
}p[MAXN];bool cmp1(const P & a,const P & b) {if(a.s == b.s) {int i=0;while(1) {if(a.rank[i] == b.rank[i]) {i++;if(a.rank.size() == i) return 0;else if(b.rank.size() == i) return 1;continue;}else return a.rank[i] < b.rank[i];}}return a.s > b.s;
}bool cmp2(const P & a,const P & b) {if(a.w == b.w) {if(a.s == b.s) {int i = 0;while(1) {if(a.rank[i] == b.rank[i]) {i++;if(a.rank.size() == i) return 0;else if(b.rank.size() == i) return 1;continue;}else return a.rank[i] < b.rank[i];}}else return a.s > b.s;}return a.w > b.w;
}int main() {int n;int a[100] = {25, 18, 15, 12, 10, 8, 6, 4, 2, 1};while(cin>>n) {for( int i=0; i<MAXN; i++ ) p[i].rank.clear(), p[i].s = 0;set<string>str;set<string>::iterator ps;int k = 0;for( int i=0; i<n; i++ ) {int m;string name;cin>>m;for( int j=0; j<m; j++ ) {cin>>name;if(str.find(name) == str.end()) {str.insert(name);p[k].name = name;p[k].s = a[j];if(j == 0) p[k].w++;//cout<<"--"<<p[0].name<<" "<<p[0].s<<endl;p[k].rank.push_back(j);k++;}else {for( int h=0; h<k; h++ ) {if(name == p[h].name) {p[h].s += a[j];if(j == 0) p[h].w++;p[h].rank.push_back(j);break;}}}}}for( int i=0; i<k; i++ ) sort(p[i].rank.begin(), p[i].rank.end());//for( int i=0; i<k; i++ ) cout<<p[i].name<<" "<<p[i].s<<endl;sort(p, p + k, cmp1);cout<<p[0].name<<endl;sort(p, p + k, cmp2);cout<<p[0].name<<endl;}return 0;
}