题目类型 简单题
题目意思
输入 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; }