跳转至

GESP 3级

B3848 [GESP样题 三级] 逛商场

B3849 [GESP样题 三级] 进制转换

提示

转进制,就是短除法

这道题目涉及到,余数和字母的转换,还有如何倒序输出

代码
#include <bits/stdc++.h>

using namespace std;

string ss = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

int main(){
    int n, r;
    cin >> n >> r;

    string s;
    while (n) {
        s += ss[n % r];
        n /= r;
    }

    reverse(s.begin(), s.end());
    cout << s;

    return 0;
}

B3842 [GESP202306 三级] 春游

代码
#include <bits/stdc++.h>

using namespace std;

bool vis[1010];
int n, m;

int main() {
    cin >> n >> m;
    while (m--) {
        int x;
        cin >> x;
        vis[x] = true;
    }

    // 遍历一遍,看vis哪些是false
    bool flag = false;
    for (int i = 0; i < n; i++)
        if (!vis[i]) cout << i << ' ', flag = true;

    if (!flag) cout << n << endl;

    return 0;
}

B3843 [GESP202306 三级] 密码合规

提示

大写、小写、数字,至少有两种

使用 a + b + c >= 2

if (a + b + c >= 2 && d == 1) return true;

代码
// 输入string
// 每个逗号之间拆分出来密码,判断是否合法
// 长度合法
// 小写、大写、数字、4个特殊字符
// 大写、小写、数字,至少有两种
// 特殊字符必须有

#include <bits/stdc++.h>

using namespace std;

string s;

bool check(string s) {
    int len = s.size();
    if (len < 6 || len > 12) return false;
    int a = 0, b = 0, c = 0, d = 0;
    for (int i = 0; i < len; i++) {
        if (s[i] >= 'a' && s[i] <= 'z') a = 1;
        else if (s[i] >= 'A' && s[i] <= 'Z') b = 1;
        else if (s[i] >= '0' && s[i] <= '9') c = 1;
        else if (s[i] == '!' || s[i] == '@' || s[i] == '#' || s[i] == '$') d = 1;
        else return false;
    }

    if (a + b + c >= 2 && d == 1) return true;
    return false;
}

int main() {
    cin >> s;
    for (int i = 0, len = s.size(); i < len; i++) {
        string t;
        int j = i;
        while (j < len && s[j] != ',') t += s[j++];

        if (check(t)) cout << t << '\n';

        i = j;
    }


    return 0;
}

B3867 [GESP202309 三级] 小杨的储蓄

代码
// 第i天,a[i]存i元
// 0~n-1个储蓄罐,分别多少钱

#include <bits/stdc++.h>

using namespace std;

int a[1010], n, d;

int main() {
    cin >> n >> d;
    for (int i = 1; i <= d; i++) {
        int x;
        cin >> x;

        a[x] += i;
    }

    for (int i = 0; i < n; i++) cout << a[i] << ' ';

    return 0;
}

B3868 [GESP202309 三级] 进制判断

代码
#include<bits/stdc++.h>
using namespace std;
void f(string s) {
    int a = 1, b = 1, c = 1, d = 1;
    for (int i = 0, len = s.size(); i < len; i++) {
        if (s[i] >= '2') a = 0;
        if (s[i] >= '8') b = 0;
        if (s[i] > '9') c = 0;
        if (s[i] >= 'G') d = 0;
    }
    cout << a << ' ' << b << ' ' << c << ' ' <<  d << endl;
}
int main() {
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        string s;
        cin >> s;
        f(s);
    }
    return 0;
}

B3925 [GESP202312 三级] 小猫分鱼-好题

提示

这道题目,虽然超出了三级的难度。以后也不会出这种难度的题目了

但这个题目,值得分析讨论,掌握分析的过程

代码
#include <bits/stdc++.h>

using namespace std;

int main(){
    int n, i;
    cin >> n >> i;

    for (int x = 1; ; x++) {
        // 假设最后一只小猫,拿x只鱼
        // 把n只小猫分鱼的过程,模拟一遍,看有没有矛盾

        bool flag = false;

        // 最后一轮, 拿鱼时候的局面
        int fish = x * n + i;

        // 从倒数第二轮开始
        for (int j = n - 1; j >= 1; j--) {
            // 判断是不是(n-1)的倍数
            if (fish % (n - 1) != 0) {
                flag = true;
                break;
            }

            // 推一下,当前这一轮,拿鱼时候的局面
            // 迭代更新fish
            fish = fish / (n - 1) * n + i;
        }

        if (!flag) {cout << fish; break;}
    }

    return 0;
}

B3926 [GESP202312 三级] 单位转换

提示

使用map维护不同单位的比例关系

代码

```cpp

include

using namespace std;

map mpm, mpg;

int main(){ int n; cin >> n;

mpm["mm"] = 1, mpm["m"] = 1000, mpm["km"] = 1000000;
mpg["mg"] = 1, mpg["g"] = 1000, mpg["kg"] = 1000000;

while (n--) {
    int x, y;
    string xx, yy;
    char c;

    cin >> x >> xx >> c >> c >> yy;

    if (mpm.count(xx) != 0) {
        cout << x << ' ' << xx << " = " << x * mpm[xx] / mpm[yy] << ' ' << yy << endl;
    }
    else {
        cout << x << ' ' << xx << " = " << x * mpg[xx] / mpg[yy] << ' ' << yy << endl;
    }
}

    return 0;
}
```

B3956 [GESP202403 三级] 字母求和

代码
// 小写字母代表1-26
// 大写字母代表负的ASCII
#include <bits/stdc++.h>

using namespace std;

int main() {
    int n;
    string s;
    cin >> n >> s;

    int sum = 0;
    for (auto c : s) {
        if (c >= 'a' && c <= 'z') sum += c - 'a' + 1;
        if (c >= 'A' && c <= 'Z') sum += -int(c);
    }

    cout << sum;

    return 0;
}

B3957 [GESP202403 三级] 完全平方数

代码
#include <bits/stdc++.h>

using namespace std;

int a[1010], n, cnt;

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i];

    for (int i = 1; i <= n; i++)
        for (int j = i + 1; j <= n; j++) {
            int x = a[i] + a[j];

            int t = sqrt(x);
            if (t * t == x) cnt++;
        }

    cout << cnt;

    return 0;
}

B4003 [GESP202406 三级] 移位

代码
#include <bits/stdc++.h>

using namespace std;

int main() {
    int n;
    cin >> n;

    for (int i = 0; i < 26; i++) {
        cout << char('A' + (i + n) % 26);
    }

    return 0;
}

B4004 [GESP202406 三级] 寻找倍数

提示

要找一个数,是所有数的倍数

那么这个数,一定是最大的

所以,我们先打擂台找出最大的数

然后再for一遍,看是不是所有数的倍数

代码
#include<bits/stdc++.h>

using namespace std;

const int N = 1e5 + 10;

int a[N], n, T;

int main() {
    cin >> T;
    while (T--) {
        cin >> n;

        int maxn = -1;
        for (int i = 1; i <= n; i++) {
            cin >> a[i];
            maxn = max(maxn, a[i]);
        }

        bool flag = false;
        for (int i = 1; i <= n; i++) 
            if (maxn % a[i] != 0) {flag = true; break;}

        if (!flag) cout << "Yes" << endl;
        else cout << "No" << endl;
    }

    return 0;
}

B4038 [GESP202409 三级] 平衡序列

提示

// 多组测试数据

// 判断数列前面的和与后面的和时候相等

// 枚举分割的点

// 前i个数的和,可以一边遍历,一边累加

// 后面的和,就可以直接用sum 减掉前面的

提示02

// 学习一下前缀和

代码
#include <bits/stdc++.h>

using namespace std;

int a[10010], n, T;

int main() {
    cin >> T;
    while (T--) {
        cin >> n;

        int sum = 0;
        for (int i = 1; i <= n; i++) {cin >> a[i]; sum += a[i];}

        bool flag = false;
        int pre = 0;
        for (int i = 1; i <= n; i++) {
            pre += a[i];
            if (pre == sum - pre) {flag = true; break;}
        }

        if (flag) cout << "Yes" << endl;
        else cout << "No" << endl;  
    }

    return 0;
}

// 注意,pre == sum - pre
// 写成,pre == sum / 2,是不科学的,因为不整除的问题,会带来错误
代码02
#include <bits/stdc++.h>

using namespace std;

int a[10010], n, T;
int s[10010];

int main() {
    cin >> T;
    while (T--) {
        cin >> n;

        int sum = 0;
        for (int i = 1; i <= n; i++) {
            cin >> a[i];
            s[i] = s[i - 1] + a[i];
        }

        bool flag = false;
        for (int i = 1; i < n; i++) {
            if (s[i] == s[n] - s[i]) {flag = true; break;}
        }

        if (flag) cout << "Yes" << endl;
        else cout << "No" << endl;  
    }

    return 0;
}

B4039 [GESP202409 三级] 回文拼接

提示

// 判断字符串是否由两个长度至少为2的回文串拼接而成

// 将字符串切割成两个字符串

// 要枚举分割的点,然后判断左右两边是否为回文

// 需要使用substr

提示02

判断回文的方式,有两种,下面示范的两种都需要熟练

代码
#include <bits/stdc++.h>

using namespace std;

bool check(string s) {
    string t = s;
    reverse(t.begin(), t.end());

    return t == s;
}

int main() {
    int n;
    cin >> n;

    while (n--) {
        string s;
        cin >> s;

        bool flag = false;
        for (int i = 2, len = s.size(); i < len - 1; i++) {
            string s1 = s.substr(0, i), s2 = s.substr(i);
            if (check(s1) && check(s2)) {flag = true; break;}
        }

        if (flag) cout << "Yes" << endl;
        else cout << "No" << endl;
    }

    return 0;
}
代码02
#include <bits/stdc++.h>

using namespace std;

bool check(string s) {
    int l = 0, r = s.size() - 1;
    while (l < r) {
        if (s[l] != s[r]) return false;
        l++, r--;
    }

    return !(l < r);
}

int main() {
    int n;
    cin >> n;

    while (n--) {
        string s;
        cin >> s;

        bool flag = false;
        for (int i = 2, len = s.size(); i < len - 1; i++) {
            string s1 = s.substr(0, i), s2 = s.substr(i);
            if (check(s1) && check(s2)) {flag = true; break;}
        }

        if (flag) cout << "Yes" << endl;
        else cout << "No" << endl;
    }

    return 0;
}

B4066 [GESP202412 三级] 数字替换

提示

// 数组读入,遍历

// 注意开数组的大小

// 打擂台,注意初始化的大小

代码
#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 10;

int a[N], n, k;
int maxn = -2e9, minn = 2e9;

int main() {
    cin >> n >> k;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        maxn = max(maxn, a[i]);
        minn = min(minn, a[i]);
    }

    for (int i = 1; i <= n; i++) {
        if (a[i] > k) a[i] = maxn;
        if (a[i] < k) a[i] = minn;
    }

    for (int i = 1; i <= n; i++) cout << a[i] << ' ';


    return 0;
}

B4067 [GESP202412 三级] 打印数字

代码
// 可以写很多个if
// 也可以把输出预存在一个二维数组里

#include <bits/stdc++.h>

using namespace std;

string ss[5][5] = {
    {".....", "****.", ".....", "....."},
    {".***.", "****.", "****.", "****."},
    {".***.", "****.", ".....", "....."},
    {".***.", "****.", ".****", "****."},
    {".....", "****.", ".....", "....."}
};

int main() {
    string s;
    cin >> s;

    for (int i = 0; i < 5; i++) {
        for (auto c : s) cout << ss[i][c - '0'];
        cout << endl;
    }

    return 0;
}

B4261 [GESP202503 三级] 2025

提示

// 这道题目本质上考察的是枚举

// 但经过观察样例,可以发现是有规律的

代码
#include <bits/stdc++.h>

using namespace std;

int main() {
    int x;
    cin >> x;

    cout << 2025 - x;

    return 0;
}

B4262 [GESP202503 三级] 词频统计

代码
// map维护
#include <bits/stdc++.h>

using namespace std;

int n;
map<string, int> mp;
int maxn;
string maxs;

int main() {
    cin >> n;
    while (n--) {
        string s;
        cin >> s;

        for (int i = 0, len = s.size(); i < len; i++)
            if (s[i] >= 'A' && s[i] <= 'Z') s[i] += 32;

        mp[s]++;

        if (mp[s] > maxn) maxn = mp[s], maxs = s;
    }

    cout << maxs;

    return 0;
}

B4358 [GESP202506 三级] 奇偶校验

代码
// 二进制下有多少个1
#include <bits/stdc++.h>

using namespace std;

int n, sum;

int main() {
    cin >> n;
    while (n--) {
        int x;
        cin >> x;

        while (x) {
            if (x % 2 == 1) sum++;
            x /= 2;
        }
    }

    cout << sum << ' ' << (sum & 1);

    return 0;
}
代码02
// 二进制下有多少个1
#include <bits/stdc++.h>

using namespace std;

int n, sum;

int main() {
    cin >> n;
    while (n--) {
        int x;
        cin >> x;

        sum += __builtin_popcount(x);
    }

    cout << sum << ' ' << (sum & 1);

    return 0;
}

B4359 [GESP202506 三级] 分糖果

提示

// 模拟样例1

4

1 4 3 3

1 4 5 6

代码
#include <bits/stdc++.h>

using namespace std;

int a[1010], b[1010], n;
long long sum;

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i];

    for (int i = 1; i <= n; i++) {
        if (i == 1) b[i] = a[i];
        else b[i] = max(b[i - 1] + 1, a[i]);

        sum += b[i];
    }

    cout << sum;

    return 0;
}

B4413 [GESP202509 三级] 数组清零

代码
// 每次用最大减去最小,直到数组全是0
// 输出操作次数
#include <bits/stdc++.h>

using namespace std;

int a[110], n, cnt;

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i];

    while (true) {
        int maxn = -1, minn = 110, k;
        for (int i = 1; i <= n; i++) {
            if (a[i] >= maxn) maxn = a[i], k = i;
            if (a[i] && a[i] < minn) minn = a[i];
        }

        a[k] -= minn;
        cnt++;

        // 全是0
        bool flag = false;
        for (int i = 1; i <= n; i++) if (a[i]) flag = true;
        if (!flag) break;
    }

    cout << cnt;

    return 0;
}

// 判断跳出循环,也可以用最小值是0,来结束循环
// 但是这样写不对,如果数组默认都是0,那这个是有错误的
代码02
// 每次用最大减去最小,直到数组全是0
// 输出操作次数
#include <bits/stdc++.h>

using namespace std;

int a[110], n, cnt;

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i];

    while (true) {
        // 上来先判断都是0的情况,就ok了
        // 全是0
        bool flag = false;
        for (int i = 1; i <= n; i++) if (a[i]) flag = true;
        if (!flag) break;

        int maxn = -1, minn = 110, k;
        for (int i = 1; i <= n; i++) {
            if (a[i] >= maxn) maxn = a[i], k = i;
            if (a[i] && a[i] < minn) minn = a[i];
        }

        a[k] -= minn;
        cnt++;

    }

    cout << cnt;

    return 0;
}

// 判断跳出循环,也可以用最小值是0,来结束循环

B4414 [GESP202509 三级] 日历制作

提示

我们发现,这道题目,只问2025年的,所以12个月的日历是固定的

在考场上,可以直接输出

我们在练习的时候,不允许直接输出,通过代码推m月的1号是星期几

代码
// MON TUE WED THU FRI SAT SUN
// 0   1   2   3   4   5   6
#include <bits/stdc++.h>

using namespace std;

int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int m;

int main() {
    cin >> m;

    int t = 0;
    if (m > 9) {
        for (int i = 9; i < m; i++) t = (t + mon[i]) % 7;
    }
    if (m < 9) {
        for (int i = 9 - 1; i >= m; i--) t = (t - mon[i]) % 7;
        t = (t + 7) % 7;
    }

//  printf("---%d\n", t);

    printf("MON TUE WED THU FRI SAT SUN\n");
    for (int i = 0; i < t; i++) printf("    ");
    for (int i = 1; i <= mon[m]; i++) {
        printf("%3d ", i);
        t++;
        if (t == 7) {t = 0; cout << endl;}
    }

    return 0;
}

B4449 [GESP202512 三级] 密码强度

提示

// 字符串

// 至少包含,用flag进行控制

代码
#include <bits/stdc++.h>

using namespace std;

int main() {
    int T;
    cin >> T;
    while (T--) {
        string s;
        cin >> s;

        bool A = false, B = false;
        for (auto c : s) {
            if (c >= 'A' && c <= 'Z') A = true;
            if (c >= '0' && c <= '9') B = true;
        }

        if (s.size() >= 8 && A && B) cout << 'Y' << endl;
        else cout << 'N' << endl;
    }


    return 0;
}

B4450 [GESP202512 三级] 小杨的智慧购物

提示

// 每种物品买最便宜的,打擂台

代码
#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 10;
int a[N], n, m;

int main() {
    memset(a, 0x3f, sizeof a);

    cin >> m >> n;
    for (int i = 1; i <= n; i++) {
        int k, p;
        cin >> k >> p;

        a[k] = min(a[k], p);
    }

    int sum = 0;
    for (int i = 1; i <= m; i++) sum += a[i];
    cout << sum;

    return 0;
}