1

GESP认证C++编程真题解析 | 202306 三级

​欢迎大家订阅我的专栏:算法题解:C++与Python实现
本专栏旨在帮助大家从基础到进阶 ,逐步提升编程能力,助力信息学竞赛备战!

专栏特色
1.经典算法练习:根据信息学竞赛大纲,精心挑选经典算法题目,提供清晰的代码实现与详细指导,帮助您夯实算法基础。
2.系统化学习路径:按照算法类别和难度分级,从基础到进阶,循序渐进,帮助您全面提升编程能力与算法思维。

适合人群:

  • 准备参加蓝桥杯、GESP、CSP-J、CSP-S等信息学竞赛的学生
  • 希望系统学习C++/Python编程的初学者
  • 想要提升算法与编程能力的编程爱好者

附上汇总帖:GESP认证C++编程真题解析 | 汇总


编程题

B3842 春游

【题目来源】

洛谷:[B3842 GESP202306 三级] 春游 - 洛谷

【题目描述】

老师带领同学们春游。已知班上有 \(N\) 位同学,每位同学有从 \(0\)\(N-1\) 的唯一编号。到了集合时间,老师确认是否所有同学都到达了集合地点,就让同学们报出自己的编号。到达的同学都会报出自己的编号,不会报出别人的编号,但有的同学很顽皮,会多次报出。你能帮老师找出有哪些同学没有到达吗 ?。

【输入】

输入包含 \(2\) 行。第一行包含两个整数 \(N\)\(M\),表示班级有 \(N\) 位同学,同学们共有 \(M\) 次报出编号。约定 \(2 \le N,M \le 1000\)
第二行包含 \(M\) 个整数,分别为 \(M\) 次报出的编号。约定所有编号是小于 \(N\) 的非负整数。

【输出】

输出一行。如果所有同学都到达,则输出 \(N\);否则由小到大输出所有未到达的同学编号,空格分隔。

【输入样例】

3 3
0 2 1

【输出样例】

3

【算法标签】

《洛谷 B3842 春游》 #数组# #GESP# #2023#

【代码详解】

#include <bits/stdc++.h>
using namespace std;

const int N = 1005;  // 最大范围
int n, m;            // n: 范围[0,n-1]   m: 已标记的数字个数
int a[N];            // 标记数组,a[i]=1表示数字i被标记,a[i]=0表示未标记
bool flag = 0;       // 标记是否有未标记的数字

int main()
{
    // 输入范围n和已标记数字数量m
    cin >> n >> m;
    
    // 读入m个已标记的数字
    while (m--)
    {
        int x;  // 当前标记的数字
        cin >> x;
        a[x] = 1;  // 标记这个数字
    }
    
    // 遍历范围[0, n-1],输出未标记的数字
    for (int i = 0; i <= n - 1; i++)
    {
        if (a[i] == 0)  // 如果数字i未标记
        {
            cout << i << " ";  // 输出这个数字
            flag = 1;           // 标记有未标记的数字
        }
    }
    
    // 如果没有找到任何未标记的数字
    if (!flag)
    {
        cout << n << endl;  // 输出n
    }
    
    return 0;
}

【运行结果】

3 3
0 2 1
3

B3843 密码合规

【题目来源】

洛谷:[B3843 GESP202306 三级] 密码合规 - 洛谷

【题目描述】

网站注册需要有用户名和密码,编写程序以检查用户输入密码的有效性。合规的密码应满足以下要求 :。

  1. 只能由 \(\texttt a \sim \texttt z\) 之间 \(26\) 个小写字母、\(\texttt A \sim \texttt Z\) 之间 \(26\) 个大写字母、\(0 \sim 9\) 之间 \(10\) 个数字以及 !@#$ 四个特殊字符构成。
  2. 密码最短长度 \(:6\) 个字符,密码最大长度 \(:12\) 个字符。
  3. 大写字母,小写字母和数字必须至少有其中两种,以及至少有四个特殊字符中的一个。

【输入】

输入一行不含空格的字符串。约定长度不超过 \(100\)。该字符串被英文逗号分隔为多段,作为多组被检测密码。

【输出】

输出若干行,每行输出一组合规的密码。输出顺序以输入先后为序,即先输入则先输出。

【输入样例】

seHJ12!@,sjdkffH$123,sdf!@&12HDHa!,123&^YUhg@!

【输出样例】

seHJ12!@
sjdkffH$123

【算法标签】

《洛谷 B3843 密码合规》 #字符串(入门)# #GESP# #2023#

【代码详解】

#include <bits/stdc++.h>
using namespace std;

string s;  // 输入字符串,包含多个以逗号分隔的密码

/**
 * 检查单个密码是否符合要求
 * 密码要求:
 * 1. 长度在6到12个字符之间
 * 2. 至少包含以下字符类型中的2种:
 *    - 大写字母
 *    - 小写字母
 *    - 数字
 * 3. 必须包含特殊字符:! @ # $ 之一
 * 4. 只能包含允许的字符(大小写字母、数字、!@#$)
 * 
 * @param t 要检查的密码字符串
 * @return 如果符合要求返回true,否则返回false
 */
bool check(string t)
{
    // 调试用,可查看每次检查的密码
    // cout << "t " << t << endl; 
    
    // 检查1:密码长度必须在6到12个字符之间
    if (t.size() < 6 || t.size() > 12)
        return false;
    
    // 标志变量,用于检查字符类型
    bool flagA = false;  // 是否包含大写字母
    bool flaga = false;  // 是否包含小写字母
    bool flag1 = false;  // 是否包含数字
    bool flag2 = false;  // 是否包含特殊字符(!@#$)
    
    // 第一次遍历:检查字符类型
    for (int i = 0; i < t.size(); i++)
    {
        if (isupper(t[i]))  // 检查是否为大写字母
            flagA = 1;
        else if (islower(t[i]))  // 检查是否为小写字母
            flaga = 1;
        else if (isdigit(t[i]))  // 检查是否为数字
            flag1 = 1;
        
        // 检查是否为特殊字符
        if (t[i] == '!' || t[i] == '@' || t[i] == '#' || t[i] == '$')
            flag2 = 1;
    }
    
    // 检查2:至少包含大写字母、小写字母、数字中的2种
    if (flagA + flaga + flag1 < 2)
        return false;
    
    // 检查3:必须包含特殊字符!@#$之一
    if (!flag2)
        return false;
    
    // 第二次遍历:检查是否只包含允许的字符
    for (int i = 0; i < t.size(); i++)
    {
        // 只允许:大小写字母、数字、特殊字符!@#$
        if (!(islower(t[i]) || isupper(t[i]) || isdigit(t[i]) ||
              t[i] == '!' || t[i] == '@' || t[i] == '#' || t[i] == '$'))
            return false;
    }
    
    // 所有检查都通过
    return true;
}

int main()
{
    // 输入密码字符串,以逗号分隔多个密码
    cin >> s;
    
    int n = s.size();  // 获取输入字符串的长度
    
    // 在字符串前添加一个空格,方便处理
    s = " " + s;
    
    string t = "";  // 临时字符串,用于存储一个密码
    
    // 遍历输入字符串,以逗号为分隔符分割密码
    for (int i = 1; i <= n; i++)
    {
        if (s[i] != ',')
        {
            // 如果不是逗号,追加到当前密码
            t += s[i];
        }
        else
        {
            // 遇到逗号,检查当前密码
            if (check(t))
                cout << t << endl;  // 密码有效,输出
            
            t = "";  // 重置临时字符串,准备处理下一个密码
        }
    }
    
    // 检查最后一个密码(末尾没有逗号)
    if (check(t))
        cout << t << endl;
    
    return 0;
}

【运行结果】

seHJ12!@,sjdkffH$123,sdf!@&12HDHa!,123&^YUhg@!
seHJ12!@
sjdkffH$123
posted @ 2026-01-18 21:03  热爱编程的通信人  阅读(3)  评论(0)    收藏  举报