GESP认证C++编程真题解析 | 202312 四级
欢迎大家订阅我的专栏:算法题解:C++与Python实现!
本专栏旨在帮助大家从基础到进阶 ,逐步提升编程能力,助力信息学竞赛备战!
专栏特色
1.经典算法练习:根据信息学竞赛大纲,精心挑选经典算法题目,提供清晰的代码实现与详细指导,帮助您夯实算法基础。
2.系统化学习路径:按照算法类别和难度分级,从基础到进阶,循序渐进,帮助您全面提升编程能力与算法思维。
适合人群:
- 准备参加蓝桥杯、GESP、CSP-J、CSP-S等信息学竞赛的学生
- 希望系统学习C++/Python编程的初学者
- 想要提升算法与编程能力的编程爱好者
附上汇总帖:GESP认证C++编程真题解析 | 汇总
编程题
B3927 小杨的字典
【题目来源】
洛谷:[B3927 GESP202312 四级] 小杨的字典 - 洛谷
【题目描述】
在遥远的星球,有两个国家 A 国和 B 国,他们使用着不同的语言:A 语言和 B 语言。小杨是 B 国的翻译官,他的工作是将 A 语言的文章翻译成 B 语言的文章。
为了顺利完成工作,小杨制作了一本字典,里面记录了 \(N\) 个 A 语言单词对应的 B 语言单词,巧合的是,这些单词都由地球上的 26 个小写英文字母组成。
小杨希望你写一个程序,帮助他根据这本字典翻译一段 A 语言文章。这段文章由标点符号 !()-[]{}\|;:'",./?<> 和一些 A 语言单词构成,每个单词之间必定由至少一个标点符号分割,你的程序需要把这段话中的所有 A 语言单词替换成它的 B 语言翻译。特别地,如果遇到不在字典中的单词,请使用大写 UNK 来替换它。
例如,小杨的字典中包含 \(2\) 个 A 语言单词 abc 和 d,它们的 B 语言翻译分别为 a 和 def,那么我们可以把 A 语言文章 abc.d.d.abc.abcd. 翻译成 B 语言文章 a.def.def.a.UNK. 其中,单词 abcd 不在词典内,因此我们需要使用 UNK 来替换它。
【输入】
第一行一个整数 \(N\),表示词典中的条目数。保证 \(N \le 100\)。
接下来 \(N\) 行,每行两个用单个空格隔开的字符串 \(A\), \(B\) ,分别表示字典中的一个 A 语言单词以及它对应的 B 语言翻译。保证所有 \(A\) 不重复;保证 \(A\) 和 \(B\) 的长度不超过 \(10\)。
最后一行一个字符串 \(S\) ,表示需要翻译的 A 语言文章。保证字符串 \(S\) 的长度不超过 \(1000\),保证字符串 \(S\) 只包含小写字母以及标点符号 !()-[]{}\|;:'",./?<> 。
【输出】
输出一行,表示翻译后的结果。
【输入样例】
2
abc a
d def
abc.d.d.abc.abcd.
【输出样例】
a.def.def.a.UNK.
【算法标签】
《洛谷 B3927 小杨的字典》 #GESP# #2023#
【代码详解】
#include <bits/stdc++.h>
using namespace std;
int n; // 字典条目数
map<string, string> mp; // 字典:单词 -> 翻译
int main()
{
// 输入字典大小
cin >> n;
// 读入字典
for (int i = 1; i <= n; i++)
{
string a, b;
cin >> a >> b; // a: 单词, b: 翻译
mp[a] = b; // 建立映射
}
// 输入待翻译的字符串
string s;
cin >> s;
string t = ""; // 临时存储当前识别的单词
int i;
// 遍历输入字符串
for (i = 0; i < s.size(); i++)
{
// 如果是小写字母,加入到当前单词
if (islower(s[i]))
{
t += s[i];
}
else
{
// 遇到非小写字母,表示单词结束
if (t != "")
{
// 查找字典
if (mp.count(t))
{
cout << mp[t]; // 输出翻译
}
else
{
cout << "UNK"; // 未知单词
}
t = ""; // 清空临时单词
}
// 输出当前的非字母字符(保持原样)
cout << s[i];
}
}
// 处理末尾可能剩余的单词
if (t != "")
{
if (mp.count(t))
{
cout << mp[t];
}
else
{
cout << "UNK";
}
}
// 问题:这里输出s[i]会越界,因为循环结束i==s.size()
// 应该是想要输出最后一个字符?但实际不应该在这里输出
// cout << s[i]; // 这行应该删除
return 0;
}
【运行结果】
2
abc a
d def
abc.d.d.abc.abcd.
a.def.def.a.UNK.
B3928 田忌赛马
【题目来源】
洛谷:[B3928 GESP202312 四级] 田忌赛马 - 洛谷
【题目描述】
你要和田忌赛马。你们各自有 \(N\) 匹马,并且要进行 \(N\) 轮比赛,每轮比赛,你们都要各派出一匹马决出胜负。
你的马匹的速度分别为 \(u_1,u_2,\cdots,u_n\),田忌的马匹的速度分别为 \(v_1,v_2,\cdots,v_n\)。田忌会按顺序派出他的马匹,请问你要如何排兵布阵,才能赢得最多轮次的比赛?巧合的是,你和田忌的所有马匹的速度两两不同,因此不可能出现平局。
【输入】
第一行一个整数 \(N\)。保证 \(1\le N \le 5\times 10^4\)
接下来一行 \(N\) 个用空格隔开的整数,依次为 \(u_1,u_2,\cdots,u_n\),表示你的马匹们的速度。保证 \(1\le u_i\le 2N\)。
接下来一行 \(N\) 个用空格隔开的整数,依次为 \(v_1,v_2,\cdots,v_n\),表示田忌的马匹们的速度。保证 \(1\le v_i\le 2N\)。
【输出】
输出一行,表示你最多能获胜几轮。
【输入样例】
3
1 3 5
2 4 6
【输出样例】
2
【算法标签】
《洛谷 B3928 田忌赛马》 #贪心# #排序# #双指针two-pointer# #GESP# #2023#
【代码详解】
#include <bits/stdc++.h>
using namespace std;
const int N = 50005; // 最大数组长度
int n; // 数组大小
int ans; // 答案:满足条件的配对数量
int u[N], v[N]; // 两个数组
int main()
{
// 输入数组大小
cin >> n;
// 输入并排序数组u
for (int i = 1; i <= n; i++)
{
cin >> u[i];
}
sort(u + 1, u + n + 1);
// 输入并排序数组v
for (int i = 1; i <= n; i++)
{
cin >> v[i];
}
sort(v + 1, v + n + 1);
// 双指针贪心匹配
int j = 1; // u数组的指针
// 遍历v数组
for (int i = 1; i <= n; i++)
{
// 跳过所有小于v[i]的u[j]
while (j <= n && u[j] < v[i])
{
j++;
}
// 调试输出
// cout << "j " << j << endl;
// 如果找到满足条件的u[j](即u[j] >= v[i])
if (j <= n)
{
ans++; // 成功配对数加1
j++; // 这个u[j]已被使用,指针后移
}
else
{
// 没有更多可用的u,提前结束
break;
}
}
// 输出结果
cout << ans << endl;
return 0;
}
【运行结果】
3
1 3 5
2 4 6
2

浙公网安备 33010602011771号