题解:P13857 [SWERC 2020] Gratitude
Sol.
题目是英文题面,这里先给出 Google 翻译过后的题面:
题面:
题目描述
本听说了埃蒙斯和麦卡洛的研究表明,刻意练习感恩会对人们的幸福感产生持久的影响。因为他也想拥有幸福,所以他决定每天结束时回顾过去的一天,并写下三件让他感恩的事情,每行一件。在练习了
输入格式
输入以一行开始,包含两个空格分隔的整数,
限制
每行输入最多包含
输出格式
输出应为 Ben 感激之事的列表,按其在 Ben 列表中出现的频率排序(频率最高的项目排在最前面)。如果两个项目的频率相同,则最近的项目应排在最前面。也就是说,如果出现次数相同,则输入中最后出现较晚的项目应在输出中更早出现。最后,如果 Ben 的列表中包含超过
分析:
由于题目要求存储 string 类型与两个 int 类型配对,自然而然就想到用 map 类型来存储。(你想用 struct ?好啊,没人拦着你!TLE 了就老实了)
然而,map 类型还是有许多的坑的,稍有不注意就会掉进去。
坑点 1:
map 类型不可用 sort!
由于 (语言研发人认为)map 类型默认有序,就不能用 sort 了!(吐槽 ing)
坑点 2:
map 类型的迭代器不可以被加一个整数!
mp.begin()+i,mp.begin()+3 这种用法全部都是错的!
言归正传。
我们创建一个结构体 node,存储要用到的计算出现次数的变量
struct node {
int id, cnt;
static node ton(int a, int b) { // 构造函数
node tmp;
tmp.cnt = a;
tmp.id = b;
return tmp;
}
};
然后,创建一个 map 类型“数组”
map <string, node> a;
之后写好一个极其复杂的比较函数
bool cmp(pair <string, node> a, pair <string, node> b) {
if (a.second.cnt != b.second.cnt) {
return a.second.cnt > b.second.cnt;
} else {
return a.second.id > b.second.id;
}
}
接下来是主函数部分,没有什么要讲的,我直接放全部代码吧:
#include <bits/stdc++.h>
using namespace std;
struct node {
int id, cnt;
static node ton(int a, int b) { // 构造函数
node tmp;
tmp.cnt = a;
tmp.id = b;
return tmp;
}
};
map <string, node> a;
string tmp;
bool cmp(pair <string, node> a, pair <string, node> b) {
if (a.second.cnt != b.second.cnt) {
return a.second.cnt > b.second.cnt;
} else {
return a.second.id > b.second.id;
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(nullptr);
int n, k;
cin >> n >> k;
cin.ignore(); // 清除换行符,避免 getline 读错字符
for (int i = 0; i < 3 * n; i++) {
getline(cin, tmp);
if (a.find(tmp) != a.end()) { // 找到了
a[tmp].cnt++;
a[tmp].id = i;
} else { // 没找到
a.insert(make_pair(tmp, node::ton(1, i))); // map 类型用 pair 实现
}
}
vector <pair <string, node> > v(a.begin(), a.end()); // map 类型不可用 sort,于是用 vector 来排序
sort(v.begin(), v.end(), cmp);
for (int i = 0; i < min((int) (v.size()), k)/*避免越界*/; i++) {
cout << v[i].first << endl;
}
return 0;
}
完结撒花
(求过 QwQ)