前言、
接(1)后完成F-H三道题
一、题目总览
二、具体题目
2.1 问题 F: 按1的个数排序:
思路:
用cin或者getline读入都可,可以整合成一个结构体放进数组中排序,也可以像我下面一样写一个pair放进vector中排序,因为pair的排序规则是先按第一个参数升序排序,再按第二个参数升序排序的,所以我们将第一个参数设置为1的个数(int),第二个参数则是字符串本身(string),这样就无须写cmp()函数或者结构体内重载小于号,最后输出即可
参考代码:
cpp
#include <bits/stdc++.h>
using i64 = long long;
using pis = std::pair<int,std::string>;
int main(){
std::cin.tie(nullptr)->sync_with_stdio(false);
std::vector<pis> v;
std::string str;
while(std::getline(std::cin,str)) {
v.emplace_back(std::count(str.begin(),str.end(),'1'),str);
}
std::sort(v.begin(),v.end());
for(auto &vi:v) {
std::cout << vi.second << '\n';
}
return 0;
}
2.2 问题 G: 排名次:
思路:
也是很经典的排序题,思路基本差不多,读入数组,然后排序,既可以以结构体的形式放入数组,然后重载小于号方便直接sort()或者写一个cmp()函数。也可以使用模板去重载pair的小于号,因为pair的排序是先按first升序排序的,我们这里的分数需要降序排序,因此需要重载小于号,当然用匿名函数也可以实现cmp()函数比较pair
参考代码1(结构体+重载小于号实现sort):
cpp
#include <bits/stdc++.h>
using i64 = long long;
struct stu {
std::string _name;
int _score;
stu(std::string name,int score):_name(name),_score(score){}
bool operator < (const stu& W) const {
if(_score!=W._score) return _score>W._score;
return _name<W._name;
}
};
int main(){
std::cin.tie(nullptr)->sync_with_stdio(false);
int n;std::cin >> n;
std::vector<stu> v;
std::string name;
int score;
for(int i = 0;i<n;i++) {
std::cin >> name >> score;
v.emplace_back(name,score);
}
std::sort(v.begin(),v.end());
for(auto &vi:v) {
std::cout << vi._name << ' ' << vi._score << '\n';
}
return 0;
}
参考代码2(结构体+cmp函数实现sort):
cpp
#include <bits/stdc++.h>
using i64 = long long;
struct stu {
std::string _name;
int _score;
stu(std::string name,int score):_name(name),_score(score){}
};
bool cmp(const stu &stu1,const stu &stu2) {
if(stu1._score!=stu2._score) return stu1._score>stu2._score;
return stu1._name<stu2._name;
}
int main(){
std::cin.tie(nullptr)->sync_with_stdio(false);
int n;std::cin >> n;
std::vector<stu> v;
std::string name;
int score;
for(int i = 0;i<n;i++) {
std::cin >> name >> score;
v.emplace_back(name,score);
}
std::sort(v.begin(),v.end(),cmp);
for(auto &vi:v) {
std::cout << vi._name << ' ' << vi._score << '\n';
}
return 0;
}
参考代码3(重载pair的小于号不太方便,于是考虑创建模板实现pair比较的结构体,重载()后sort时调用):
cpp
#include <bits/stdc++.h>
using i64 = long long;
using pis = std::pair<int,std::string>;
template<typename T1,typename T2>
struct PairCmp {
bool operator()(const std::pair<T1,T2> &p1,const std::pair<T1,T2> &p2) const{
if(p1.first!=p2.first) return p1.first>p2.first;
return p1.second<p2.second;
}
};
using PisCmp = PairCmp<int,std::string>;
int main(){
std::cin.tie(nullptr)->sync_with_stdio(false);
int n;std::cin >> n;
std::vector<pis> v;
std::string name;
int score;
for(int i = 0;i<n;i++) {
std::cin >> name >> score;
v.emplace_back(score,name);
}
std::sort(v.begin(),v.end(),PisCmp());
for(auto &vi:v) {
std::cout << vi.second << ' ' << vi.first << '\n';
}
return 0;
}
参考代码4(匿名函数实现std::pair<int,std::string>进行sort):
cpp
#include <bits/stdc++.h>
using i64 = long long;
using pis = std::pair<int,std::string>;
int main() {
std::cin.tie(nullptr)->sync_with_stdio(false);
int n;std::cin >> n;
std::vector<pis> v;
std::string name;
int score;
for(int i = 0;i<n;i++) {
std::cin >> name >> score;
v.emplace_back(score,name);
}
auto cmp = [&](const pis& stu1,const pis& stu2) ->bool {
if(stu1.first!=stu2.first) return stu1.first>stu2.first;
return stu1.second<stu2.second;
};
std::sort(v.begin(),v.end(),cmp);
for(auto &vi:v) {
std::cout << vi.second << ' ' << vi.first << '\n';
}
return 0;
}
2.3 问题 H: 子字符串排序:
思路:
这是一个新题,应该是从codeforces上搬运过来的,因为放在string和sort的练习专题里,考虑贪心和排序,先按字符串的长度升序排序,然后根据字典序排序,排序好之后check一遍,是否前者是后者的子集,这里可以考虑用string的find函数
参考代码:
cpp
#include <bits/stdc++.h>
using i64 = long long;
int main() {
std::cin.tie(nullptr)->sync_with_stdio(false);
int n;
std::cin >> n;
std::vector<std::string> v;
std::string str;
for(int i = 0;i<n;i++) {
std::cin >> str;
v.emplace_back(str);
}
std::sort(v.begin(),v.end(),[&](const std::string &s1,const std::string &s2)->bool {
if(s1.size()!=s2.size()) return s1.size() < s2.size();
return s1 < s2;
});
auto check = [&]()->bool {
for(int i = 0;i<v.size()-1;i++) {
if(v[i+1].find(v[i])==std::string::npos) return false;
}
return true;
};
if (check()) {
std::cout << "YES\n";
for(auto &vi:v) {
std::cout << vi << '\n';
}
}else {
std::cout << "NO\n";
}
return 0;
}