题目描述
每个魔法师都会有N个朋友,每个人的名字都由“姓”和“名”两部分组成。你需要把他们按照姓的“流行程度”(即拥有该姓的朋友人数)从大到小排序,姓的流行程度相同的朋友按照他们在原始名单中出现的顺序排序。
输入
输入包含若干行,即排序前的原始序列。每行包含一个朋友的姓和名,中间用一个空格隔开,朋友的数目保证不超过50000,每行为3到50个字符之间,且只包含大写字母和一个空格(行首行末无空格)。
输出
输出有若干行,即排序后的序列,每行包括一个朋友的姓和名,中间用一个空格隔开。
样例输入 Copy
ZHANG SAN LI SI WANG WU WANG LIU WANG QI ZHANG WU LI WU
样例输出 Copy
WANG WU WANG LIU WANG QI ZHANG SAN LI SI ZHANG WU LI WU
解析: 这里包含几个优化GCC编码的头文件,具体可见GCC编译优化和调试选项 | Walker's Blog
GCC编译器优化选项分析及具体优化了什么_OSKernelLAB(gatieme)-优快云博客
40行加速头文件_weixin_30686845的博客-优快云博客
不优化GCC编码很容易超时!
基本思路就是利用结构体定义string型(方便比较大小)的姓和名,再定义一个出现的位置(方便姓出现次数相同时,可以按默认顺序排),利用map容器表示姓和姓出现的次数,最后用sort排序输出就行了。
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
# include<iostream>
# include<iomanip>
# include<algorithm>
# include<cmath>
# include<cstdio>
# include<set>
# include<stack>
# include<vector>
# include<queue>
# include<map>
# include<string>
# include<cstring>
using namespace std;
struct student
{
string xn;
string mn;
int id;/*记录xn出现的位置*/
}a[100001];
map<string,int>q;/*使用map容器记录xn的次数可节省时间*/
int n = 0;
bool cmp(student a,student b){
if(q[a.xn] == q[b.xn ]) return a.id < b.id ;
return q[a.xn ] > q[b.xn ];
}
int main(){
std::ios::sync_with_stdio(false);/*使得cin的时间缩短*/
cin.tie(0);/*使得cin的时间缩短*/
cout.tie(0);/*使得cin的时间缩短*/
while(cin >> a[++n].xn )
{
cin >> a[n].mn ;
a[n].id = n;
q[a[n].xn]++;
}
sort(a,a+n,cmp);
for(int i = 0 ; i < n-1 ; i ++ )
cout<<a[i].xn <<" "<<a[i].mn <<"\n";
return 0;
}