第十届蓝桥杯C/C++ A组

试题 A: 平方和
本题总分:5 分
【问题描述】
小明对数位中含有 2、0、1、9 的数字很感兴趣,在 1 到 40 中这样的数包
括 1、2、9、10 至 32、39 和 40,共 28 个,他们的和是 574,平方和是 14362。
注意,平方和是指将每个数分别平方后求和。
请问,在 1 到 2019 中,所有这样的数的平方和是多少
答案:2658417853

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

bool check(int x)
{
    while (x)
    {
        int t = x % 10;
        if (t == 2 || t == 0 || t == 1 || t == 9) return true;
        x /= 10;
    }
    return false;
}

int main()
{
    long long res = 0;
    for (int i = 1; i <= 2019; i ++)
    {
        if (check(i)) res += i * i;
    }
    cout << res << endl;
}

试题 B: 数列求值
本题总分:5 分
【问题描述】
给定数列 1, 1, 1, 3, 5, 9, 17, …,从第 4 项开始,每项都是前 3 项的和。求
第 20190324 项的最后 4 位数字。

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

const int N = 100010;

int f[4][N];

int main()
{
    int a = 1, b = 1, c = 1, d;
    
    for (int i = 4; i <= 20190324; i ++ )
    {
        d = (a + b + c) % 1000;
        a = b;
        b = c;
        c = d;
    }
    cout << d << endl;
    
    return 0;
}

试题 C: 最大降雨量
本题总分:10 分
【问题描述】
由于沙之国长年干旱,法师小明准备施展自己的一个神秘法术来求雨。
这个法术需要用到他手中的 49 张法术符,上面分别写着 1 至 49 这 49 个
数字。法术一共持续 7 周,每天小明都要使用一张法术符,法术符不能重复使
用。
每周,小明施展法术产生的能量为这周 7 张法术符上数字的中位数。法术
施展完 7 周后,求雨将获得成功,降雨量为 7 周能量的中位数。
由于干旱太久,小明希望这次求雨的降雨量尽可能大,请大最大值是多少?

答案:34

试题 D: 迷宫
本题总分:10 分
【问题描述】
下图给出了一个迷宫的平面图,其中标记为 1 的为障碍,标记为 0 的为可
以通行的地方。
010000
000100
001001
110000
迷宫的入口为左上角,出口为右下角,在迷宫中,只能从一个位置走到这
个它的上、下、左、右四个方向之一。
对于上面的迷宫,从入口开始,可以按DRRURRDDDR 的顺序通过迷宫,
一共 10 步。其中 D、U、L、R 分别表示向下、向上、向左、向右走。
对于下面这个更复杂的迷宫(30 行 50 列),请找出一种通过迷宫的方式,
其使用的步数最少,在步数最少的前提下,请找出字典序最小的一个作为答案。
请注意在字典序中D<L<R<U。(如果你把以下文字复制到文本文件中,请务
必检查复制的内容是否与文档中的一致。在试题目录下有一个文件 maze.txt,
内容与下面的文本相同)

答案:DDDDRRURRRRRRDRRRRDDDLDDRDDDDDDDDDDDDRDDRRRURRUURRDDDDRDRRRRRRDRRURRDDDRRRRUURUUUUUUULULLUUUURRRRUULLLUUUULLUUULUURRURRURURRRDDRRRRRDDRRDDLLLDDRRDDRDDLDDDLLDDLLLDLDDDLDDRRRRRRRRRDDDDDDRR

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;

const int N = 100;

char g[N][N];
int d[N][N];
int last[N][N];
string res = "";
int n = 30, m = 50;
int dx[5] = {1, 0, 0, -1}, dy[5] = {0, -1, 1, 0};

void bfs()
{
    queue<PII> q;
    PII k;
    k.first = 0, k.second = 0;
    q.push(k); 
    d[0][0] = 1;
    
    while (!q.empty())
    {
        PII t = q.front();
        q.pop();
        
        int a = t.first, b = t.second;
        for (int i = 0; i < 4; i ++ ){
            int x = a + dx[i], y = b + dy[i];
            if (x < 0 || x >= n || y < 0 || y >= m || g[x][y] == '1' || d[x][y]) continue;
            
            d[x][y] = d[a][b] + 1;
            last[x][y] = i + 1;
            PII w;
            w.first = x, w.second = y;
            q.push(w);
            if (x == n - 1 && y == m - 1) return;
        }
    }
    
}

void get_a(int x, int y)
{
    if (x == 0 && y == 0) return;
    if (last[x][y] == 1) res += 'D', get_a(x - 1, y);
    else if (last[x][y] == 2) res += 'L', get_a(x, y + 1);
    else if (last[x][y] == 3) res += 'R', get_a(x, y - 1);
    else if (last[x][y] == 4) res += 'U', get_a(x + 1, y);
}

int main()
{
    for (int i = 0; i < 30; i ++ )
            cin >> g[i];
    
    bfs();
    get_a(n - 1, m - 1);

    reverse(res.begin(), res.end());
    cout << res << endl;
    
    return 0;
}

试题E: RSA 解密 (数论)
【问题描述】
RSA 是一种经典的加密算法。它的基本加密过程如下。
首先生成两个质数 p, q,令 n = p · q,设 d 与 (p − 1) · (q − 1) 互质,则可找到 e 使得 d · e 除 (p − 1) · (q − 1) 的余数为 1。n, d, e 组成了私钥,n, d 组成了公钥。当使用公钥加密一个整数 X 时(小于 n),计算 C = X^d mod n,则 C 是加密后的密文。
当收到密文 C 时,可使用私钥解开,计算公式为 X = C^e mod n。例如,当 p = 5, q = 11, d = 3 时,n = 55, e = 27。若加密数字 24,得 243 mod 55 = 19。解密数字 19,得 1927 mod 55 = 24。现在你知道公钥中 n = 1001733993063167141, d = 212353,同时你截获了别人发送的密文 C = 20190324,请问,原文是多少?

答案:579706994112328949

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

LL p, q, t, d, e;
LL x, y;

LL mul(LL a, LL b, LL p)
{
    LL res = 0;
    while (b)
    {
        if (b & 1) res = (res + a) % p;
        a = (a + a) % p;
        b >>= 1;
    }
    return res;
}

LL qmi(LL a, LL k, LL p)
{
    LL res = 1;
    while (k)
    {
        if (k & 1) res = mul(res, a, p);
        a = mul(a, a, p);
        k >>= 1;
    }
    return res;
}

void exgcd(LL a, LL b)
{
    if (!b){
        x = 1, y = 0;
        return;
    }
    
    exgcd(b, a % b);
    
    LL t = x;
    x = y;
    y = t - a / b * y;
}

int main()
{
    LL n = 1001733993063167141, d = 212353;
    
    for (int i = 3; i <= n / i; i += 2)
        if (n % i == 0) p = i, q = n / i;
    cout << p << " " << q << endl;
    
    t = (p - 1) * (q - 1);
    
    if (gcd(d, t) != 1) cout << "No" << endl;
    
    exgcd(d, t);
    
    LL e = (x % t + t) % t;
    cout << e << endl;
    
    LL res = qmi(c, e, n);
    
    cout << res << endl;
    
    return 0;
}

试题F: 完全二叉树的权值 (暴力)
【问题描述】
给定一棵包含 N 个节点的完全二叉树,树上每个节点都有一个权值,按从上到下、从左到右的顺序依次是 A1, A2, · · · AN
现在小明要把相同深度的节点的权值加在一起,他想知道哪个深度的节点权值之和最大?如果有多个深度的权值和同为最大,请你输出其中最小的深度。
注:根的深度是 1。
【输入格式】
第一行包含一个整数 N。
第二行包含 N 个整数 A1, A2, · · · AN 。
【输出格式】
输出一个整数代表答案。
【样例输入】
7
1 6 5 4 3 2 1

【样例输出】
2

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

const int N = 100010;

int a[N];
int n;

int main()
{
    cin >> n;
    for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);
    
    LL res = a[1], w = 1;
    for (int i = 2, k = 2; i <= n; i *= 2, k ++ ){
        LL ans = 0;
        for (int j = i; j < i * 2; j ++ ){
            ans += a[j];
        }
        if (ans > res) {
            res = ans;
            w = k;
        }
    }
    
    cout << w << endl;
    
    return 0;
}

试题G: 外卖店优先级 (模拟)
【问题描述】
“饱了么”外卖系统中维护着 N 家外卖店,编号 1 ∼ N。每家外卖店都有一个优先级,初始时 (0 时刻) 优先级都为 0。
每经过 1 个时间单位,如果外卖店没有订单,则优先级会减少 1,最低减到 0;而如果外卖店有订单,则优先级不减反加,每有一单优先级加 2。
如果某家外卖店某时刻优先级大于 5,则会被系统加入优先缓存中;如果优先级小于等于 3,则会被清除出优先缓存。
给定 T 时刻以内的 M 条订单信息,请你计算 T 时刻时有多少外卖店在优先缓存中。
【输入格式】
第一行包含 3 个整数 N、M 和 T 。
以下 M 行每行包含两个整数 ts 和 id,表示 ts 时刻编号 id 的外卖店收到一个订单。
【输出格式】
输出一个整数代表答案。
【样例输入】
2 6 6
1 1
5 2
3 1
6 2
2 1
6 2

【样例输出】
1

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;

const int N = 100010;

int last[N], s[N];
bool st[N];
PII a[N];
int n, m, t;

int main()
{
    cin >> n >> m >> t;
    
    for (int i = 0; i < m; i ++ ) {
        int x, y;
        scanf("%d%d", &x, &y);
        a[i].first = x, a[i].second = y;
    }
    
    sort(a, a + m);
    
    for (int i = 0; i < m; i ++ ){
        int ts = a[i].first, id = a[i].second;
        
        if (ts != last[id]) s[id] -= (ts - last[id] - 1);

        if (s[id] < 0) s[id] = 0;
        if (s[id] <= 3) st[id] = false;
        
        s[id] += 2;
        if (s[id] > 5) st[id] = true;
        last[id] = ts;
    }
    
    int res = 0;
    for (int i = 1; i <= n; i ++ )
    {
        s[i] -= (t - last[i]);
        //cout << s[i] << endl;
        if (s[i] <= 3) st[i] = false;
        if (st[i]) res ++;
    }
    cout << res << endl;
    
    return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
2023年的第十四届蓝桥杯 C/C++ 大学生大赛 A 省赛是一个非常重要且具有挑战性的比赛。作为蓝桥杯系列赛事的一部分,这个比赛吸引了全国各地的大学生参与,旨在促进青年学生计算机编程技术的提高,培养他们的创新能力和团队协作精神。 参赛者需要通过线上报名,在规定的时间内上传自己的比赛作品。比赛设置了一系列难度逐渐增加的编程题目,要求选手运用C/C++语言进行编写和实现。这些题目可能涉及算法设计、数据结构、编程基础等方面的知识,考察参赛者的编码能力、解决问题的能力以及在压力下的应变能力。 在比赛中,选手不仅需要具备扎实的编程技术,还需要在有限的时间内迅速分析问题、设计解决方案,并通过编程实现。因此,参赛者需要具备良好的逻辑思维能力、数学基础和编程实践经验。 在省赛中取得好成绩的选手将有机会晋级到全国赛,进一步与全国各地的顶尖选手一较高下,争夺更好的名次和更多的奖品。 参加蓝桥杯 C/C++ 大学生大赛不仅是一次锻炼和展示自己编程能力的机会,还能结识更多志同道合的同学和业界精英,获得丰厚的奖金和荣誉。同时,参赛经历对于大学生未来的学习和职业发展也具有积极的影响。 总之,2023年第十四届蓝桥杯 C/C++ 大学生大赛 A 省赛是一个具有挑战性的比赛,参赛者需要具备扎实的编程技术和解决问题的能力。通过参与比赛,学生可以提升自己的编程能力,拓宽视野,展示个人才华,并为未来的学习和就业打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值