说明:
博主为了提早预习数据结构和C++的一些知识,自己琢磨外加查阅资料所写的代码,题目来源于22年初的学院老师组织的算法基础公选课的练习。我的代码甚至思路肯定存在许多不足和错误,欢迎大家批评指正。
题目列表:
问题 A: 删数问题(Tan1)
思路:这个题暂时没有用string和sort()写的思路,就用char a[]数组笨办法做了,遍历数组检查,找到开始不再递增的下标,然后删去该元素(字符),最后输出字符数组a即可
参考代码:
#include <bits/stdc++.h>
using namespace std;
//using ll = long long;
//using PII = pair<int,int>;
const int N = 3e2+5;
char a[N];
int main(){
//1040: 删数问题(Tan1)
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int k,i,j;cin >> a >> k;
while(k--){
i = 0;
while(i<strlen(a)&&a[i]<=a[i+1]) i++;
//剔除比前一个字符小的字符
for(j = i;j<strlen(a);j++) a[j] = a[j+1];
}
while(a[0]=='0'){//去除字符串首部的0
for(int i = 1;i<strlen(a);i++){
a[i-1] = a[i];
}
a[strlen(a)-1] = '\0';
}
cout << a << '\n';
return 0;
}
问题 B: 输出亲朋字符串
思路:循环遍历即可
参考代码:
#include <bits/stdc++.h>
using namespace std;
//using ll = long long;
//const int N = 1e4+5;
string s;
int main(){
//问题 B: 输出亲朋字符串
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin >> s;
int len = s.size();
for(int i = 0;i<len;i++){
if(i!=len-1) cout << char(s[i]+s[i+1]);
else cout << char(s[len-1]+s[0]);
}
return 0;
}
问题 C: 密钥加密
思路:注意分辨字符数字和非字符数字即可,遍历操作即可
注意:读取明文时,要一整行地读,不能使用cin,cin不能把空格读进来;读取明文之前,一定记得使用cin.get()读掉前面密钥结尾的换行符
参考代码:
#include <bits/stdc++.h>
using namespace std;
//using ll = long long;
//const int N = 1e4+5;
string a,b;
int main(){
//问题 C: 密钥加密
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
while(cin >> a){
cin.get();//读掉cin最后的换行符
getline(cin,b);
int lena = a.size();
int lenb = b.size();
for(int i = 0,j = 0;i<lenb;i++,j++){
if(j>=lena) j = 0;
if(a[j]-'0'+b[i]<=122) cout << char(a[j]-'0'+b[i]);
else cout << char(31+(a[j]-'0'+b[i])%122);
}
cout << '\n';
}
return 0;
}
问题 D: 排列对称串
思路:如果是非对称的字符串,则不存入数组,若是对称字符串,则存入数组。再对数组进行排序,使用sort()函数,注意使用容器接口即string的begin()和end(),并使用自定义函数cmp来定义排序规则。注意sort()的范围区间是左闭右开的。
参考代码:
#include <bits/stdc++.h>
using namespace std;
//using ll = long long;
//const int N = 1e4+5;
string s,ans[105];
bool isok(string s){//判断是否为对称字符串,若是则返回true,否则返回false
string temp = s;
//直接使用<algorithm>的reverse()函数翻转字符串
reverse(s.begin(),s.end());
//如果翻转前与翻转后相等,则为对称字符串
if(temp == s) return true;
else return false;
}
bool cmp(string s1,string s2){
if(s1.size()!=s2.size()) return s1.size()<s2.size();
else return s1<s2;
}
int main(){
//问题 D: 排列对称串
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int index = 0;
while(cin >> s){
if(isok(s)){
ans[index] = s;
index++;
}
}
sort(ans,ans+index,cmp);
for(int i = 0;i<index;i++) cout << ans[i] << '\n';
return 0;
}
问题 E: 《庆余年》之四大宗师
思路:这个题,我一开始以为用结构体加数组会很轻松地做出来,但是实际写起来比较麻烦。因此我这里将6场比赛存入结构体数组,然后使用了map加快寻找名字以便计算这四个人的积分。使用map遍历6次比赛计算好积分之后存入vector,再使用sort()排序,最后输出即可
参考代码:
#include <bits/stdc++.h>
using namespace std;
//using ll = long long;
//const int N = 1e4+5;
struct race{
string player1,player2;
char c;//比赛状况
}r[10];
map<string,int> mp;
bool cmp(pair<string,int> p1,pair<string,int> p2){
//先根据积分从高到低排序,再根据人名按字典序排序
if(p1.second!=p2.second) return p1.second > p2.second;
else return p1.first<p2.first;
}
int main(){
//问题 E: 《庆余年》之四大宗师
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
for(int i = 1;i<=6;i++) cin >> r[i].player1 >> r[i].player2 >> r[i].c;
//初始化四个人的积分
mp.insert(pair<string,int>("SiGuJian",0));
mp.insert(pair<string,int>("KuHe",0));
mp.insert(pair<string,int>("YeLiuYun",0));
mp.insert(pair<string,int>("QingDi",0));
//遍历6场比赛计算每个人的积分
for(int i = 1;i<=6;i++){
if(r[i].c=='S') mp[r[i].player1]+=3;
else if(r[i].c=='F') mp[r[i].player2]+=3;
else if(r[i].c=='='){mp[r[i].player1]++;mp[r[i].player2]++;}
}
//使用vector将map中的信息读取出来,方便后续的排序
vector<pair<string,int> > v(mp.begin(),mp.end());
sort(v.begin(),v.end(),cmp);
for(int i = 0;i<v.size();i++) cout << v[i].first << '\n';
return 0;
}
问题 F: 按1的个数排序
思路:开一个结构体,存放数字字串,字串的长度,1的个数信息,然后使用sort()对结构体数组进行排序,输出排序后的结果即可
参考代码:
#include <bits/stdc++.h>
using namespace std;
//using ll = long long;
const int N = 1e2+5;
struct str{
string s;//数字字串
int num;//1的数量
int len;//数字字串的长度
}a[N];
int count_num(str a1){
int count = 0;
for(int i = 0;i<a1.len;i++){
if(a1.s[i]=='1') count++;
}
return count;
}
bool cmp(str a1,str a2){
//先根据1的数量排序,再根据数字字串字典序排序
if(a1.num!=a2.num) return a1.num<a2.num;
else return a1.s<a2.s;
}
int main(){
//问题 F: 按1的个数排序
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int idx = 0;
while(cin >> a[idx].s){
a[idx].len = a[idx].s.size();
a[idx].num = count_num(a[idx]);
idx++;
}
sort(a,a+idx,cmp);
for(int i = 0;i<idx;i++) cout << a[i].s << '\n';
return 0;
}
问题 G: 排名次
思路:跟F题同理,开一个存放学生姓名和学生成绩的结构体,使用sort()对结构体数组排序,输出排序后的结果即可
参考代码:
#include <bits/stdc++.h>
using namespace std;
//using ll = long long;
const int N = 1e3+5;
struct student{
string name;//学生姓名
int score;//学生分数
}a[N];
bool cmp(student a1,student a2){
//先根据学生的分数排序,再根据学生姓名的字典序排序
if(a1.score != a2.score) return a1.score>a2.score;
else return a1.name<a2.name;
}
int main(){
//问题 G: 排名次
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int n;cin >> n;
for(int i = 1;i<=n;i++) cin >> a[i].name >> a[i].score;
sort(a+1,a+1+n,cmp);
for(int i = 1;i<=n;i++) cout << a[i].name << ' ' << a[i].score << '\n';
return 0;
}