【算法打卡day27(2026-03-19 周四)】蓝桥云课中Lv.1难度中的绝大部分题

- 第 194 篇 -
Date: 2026 - 03- 19 | 周四
Author: 郑龙浩(仟墨)
蓝桥云课中Lv.1难度中的绝大部分题

2026-03-19-算法刷题day27-难度Lv.1

我本以为Lv.1难度的所有题,除了涉及某些数学或者现实中的知识盲区的,都能做出来

没想到还是有的不是很好做,难点主要是「填空题」,要去理解写代码的人的思路,而不是自己从头构思思路,要去揣测他的想法,有的我就感觉理解起来有些困难,后面有个填空题用到了「三向切分」的思路,我就不会了,之前确实没写过这类似的代码

这个Lv.1的难度太虚了,编程题确实是Lv.1的难度,但是部分填空题,对于我来说不是Lv.1,虽然有的能蒙出来,但是整个代码我是不能理解的,且很多填空题不是纯基础题,就是个算法题

填空涉及到DP和回溯的,反正我都迷迷糊糊的,不是很明白,难受

最近还有其他比赛要搞,本来想今天把lv1和lv2的题都做一做,看来是做不完了,明天尽量做吧

文章目录

1-蓝桥云课3499-幸运数字

### 问题描述

哈沙德数是指在某个固定的进位制当中,可以被各位数字之和整除的正整数。例如 126126 是十进制下的一个哈沙德数,因为 (126)10(1+2+6)=0(126)10​mod(1+2+6)=0;126126 也是八进制下的哈沙德数,因为 (126)10=(176)8(126)10​=(176)8​ ,(126)10mod(1+7+6)=0(126)10​mod(1+7+6)=0;同时 126126 也是 1616 进制下的哈沙德数,因为 (126)10=(7e)16(126)10​=(7e)16​ ,(126)10mod(7+e)=0(126)10​mod(7+e)=0。小蓝认为,如果一个整数在二进制、八进制、十进制、十六进制下均为哈沙德数,那么这个数字就是幸运数字,第 11 至第 1010 个幸运数字的十进制表示为:1,2,4,6,8,40,48,72,120,126...1,2,4,6,8,40,48,72,120,126...。现在他想知道第 20232023 个幸运数字是多少?你只需要告诉小蓝这个整数的十进制表示即可。

答案提交

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

【思路】

纯模拟,没什么技巧

【代码】

cpp 复制代码
/* 2026-03-19-算法打卡day27
 * 1-蓝桥云课3499-幸运数字
 * 算法:
 * Author:郑龙浩
 * Date:2026-03-19
 * 用时:
 */

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;

ll newNum(ll num, int m) {
    ll ans = 0;
    while (num) {
        ans += num % m;
        num /= m;
    }
    return ans;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);

    int cnt = 0;
    for (int i = 1;; i++) {
        ll a, b, c, d;
        a = i % newNum(i, 2);
        b = i % newNum(i, 8);
        c = i % newNum(i, 10);
        d = i % newNum(i, 16);
        if (a == 0 && b == 0 && c == 0 && d == 0) cnt++;
        if (cnt == 2023) {
            cout << i;
            break;
        }
    }
    
    return 0;
}

2-蓝桥云课2379-英文字母

### 问题描述

输入一个正整数 nn, 输出第 nn 个大写英文字母。

输入格式

输入一行包含一个正整数 nn 。

输出格式

输出一行包含一个字母。

样例输入 1

text 复制代码
12

样例输出 1

text 复制代码
L

样例输入 2

TEXT 复制代码
17

样例输出 2

text 复制代码
Q

评测用例规模与约定

对于所有评测用例, 1≤n≤261≤n≤26 。

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

【思路】

没什么技巧

【代码】

cpp 复制代码
/* 2026-03-19-算法打卡day27
 * 2-蓝桥云课2379-英文字母
 * 算法:没算法
 * Author:郑龙浩
 * Date:2026-03-19
 * 用时:2min
 */

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int n; cin >> n;
    cout << (char)('A' + n - 1);
    return 0;
}

3-蓝桥云课2371-3的倍数

### 问题描述

小蓝对 3 的倍数很感兴趣。现在他手头有三个不同的数 a,b,ca,b,c, 他想知道, 这三个数中是不是有两个数的和是 3 的倍数。

例如, 当 a=3,b=4,c=6a=3,b=4,c=6 时, 可以找到 aa 和 cc 的和是 3 的倍数。 例如, 当 a=3,b=4,c=7a=3,b=4,c=7 时, 没办法找到两个数的和是 3 的倍数。

输入格式

输入三行, 每行一个整数, 分别表示 a,b,ca,b,c 。

输出格式

如果可以找到两个数的和是 3 的倍数, 输出 yes, 否则输出 no。

样例输入 1

text 复制代码
3
4
6

样例输出 1

text 复制代码
yes

样例输入 2

text 复制代码
3
4
7

样例输出 2

text 复制代码
no

评测用例规模与约定

对于所有评测用例,1≤a≤b≤c≤1001≤a≤b≤c≤100。

【思路】

没有技巧

【代码】

cpp 复制代码
/* 2026-03-19-算法打卡day27
 * 3-蓝桥云课2371-3的倍数
 * 算法:没算法
 * Author:郑龙浩
 * Date:2026-03-19
 * 用时:3min
 */

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int a, b, c;
    cin >> a >> b >> c;
    int n1 = a + b, n2 = b + c, n3 = a + c;
    n1 %= 3; n2 %= 3; n3 %= 3;
    if (n1 == 0 || n2 == 0 || n3 == 0) cout << "yes";
    else cout << "no";
    return 0;
}

4-蓝桥云课2366-双阶乘

问题描述

一个正整数的双阶乘, 表示不超过这个正整数且与它有相同奇偶性的所有 正整数乘积。 nn 的双阶乘用 n!!n!! 表示。

例如:

3!!=3×1=38!!=8×6×4×2=38411!!=11×9×7×5×3×1=10395​3!!=3×1=38!!=8×6×4×2=38411!!=11×9×7×5×3×1=10395​

请问, 2021!!2021!! 的最后 5 位 (这里指十进制位) 是多少?

注意: 2021!!=2021×2019×⋯×5×3×12021!!=2021×2019×⋯×5×3×1 。

提示: 建议使用计算机编程解决问题。

答案提交

这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一 个整数, 在提交答案时只填写这个整数, 填写多余的内容将无法得分。

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

【思路】

题目要求"最后5位",即取结果的后5位数。

  • 在乘法过程中,**更高位(第6位及之后)**​ 会不断累积

  • 但更高位不影响最终的后5位结果

  • 每次乘完立即 % 100000,相当于只保留后5位,丢弃更高位

  • 这样做可以防止数值溢出,且不影响最终答案

【代码】

cpp 复制代码
/* 2026-03-19-算法打卡day27
 * 4-蓝桥云课2366-双阶乘
 * 算法:没算法
 * Author:郑龙浩
 * Date:2026-03-19
 * 用时:5min
 */

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    ll ans = 1;
    for (ll i = 2021; i >= 1; i -= 2) {
        ans = ans * i % 100000;
    }
    cout << ans % 100000;
    return 0;
}

5-蓝桥云课2365-求余

【题目】

在 C/C++/Java/Python 等语言中, 使用 % 表示求余, 请问 2021 % 20 的值是多少?

【代码】

cpp 复制代码
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cout << 2021 % 20;
    return 0;
}

6-蓝桥云课2364-浮点数

【题目】

IEEE 754 规定一个双精度浮点数百 1 位符号位、11 位阶和 52 位尾数组成 (以上位数都表示二进制位数)。

请问,按此规定一个双精度浮点数占用几个字节?

【思路】

刚开始确实没反应过来,这是一个「位」转「字节」的题

算出「总位数」/ 「8位」,因为8位是1字节

【代码】

cpp 复制代码
/* 2026-03-19-算法打卡day27
 * 6-蓝桥云课2364-浮点数
 * 算法:没算法
 * Author:郑龙浩
 * Date:2026-03-19
 * 用时:2min
 */

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cout << (1 + 11 + 52) / 8;
    return 0;
}

7-蓝桥云课2353-日期格式

问题描述

小蓝要处理非常多的数据, 其中有一些数据是日期。

在小蓝处理的日期中有两种常用的形式: 英文形式和数字形式。

英文形式采用每个月的英文的前三个宁母作为月份标识, 后面跟两位数字 表示日期, 月份标识第一个字母大写, 后两个字母小写, 日期小于 10 时要补 前导 0s 1 月到 12 月英文的前三个字母分别是 Jan、Feb、Mar、Apr、May、 Jun、Jul、Aug、Sep、Oct、Nov、Dec:

数字形式直接用两个整数表达, 中间用一个空格分隔, 两个整数都不写前导 0。其中月份用 1 至 12 分别表示 1 月到 12 月。

输入一个日期的数字形式, 请输出它的英文形式。

输入格式

输入一行包含两个整数, 分别表示日期的月和日。

输出格式

输出对应的英文形式:

样例输入

text 复制代码
2 8

样例输出

text 复制代码
Feb08

样例输入

text 复制代码
10 18

样例输出

text 复制代码
Oct18

【思路】

简单题,但是有个注意的点,我刚开始没注意,就是输出的时候日要有「前导0」

【代码】

cpp 复制代码
/* 2026-03-19-算法打卡day27
 * 7-蓝桥云课2353-日期格式
 * 算法:没算法
 * Author:郑龙浩
 * Date:2026-03-19
 */

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    string nums[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
    int a, b; cin >> a >> b;
    cout << nums[a - 1];printf("%02d", b);
    return 0;
}

8-蓝桥云课2118-排列字母

【题目】

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

小蓝要把一个字符串中的字母按其在字母表中的顺序排列。

例如,LANQIAO 排列后为 AAILNOQ。

又如,GOODGOODSTUDYDAYDAYUP 排列后为 AADDDDDGGOOOOPSTUUYYY。

请问对于以下字符串,排列之后字符串是什么?

WHERETHEREISAWILLTHEREISAWAY

【代码】

cpp 复制代码
/* 2026-03-19-算法打卡day27
 * 8-蓝桥云课2118-排列字母
 * 算法:没算法
 * Author:郑龙浩
 * Date:2026-03-19
 */

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    string s; cin >> s;
    
    sort(s.begin(), s.end());
    cout << s;
    return 0;
}

9-蓝桥云课2095-九进制转十进制

【题目】

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

九进制正整数 (2022)9转换成十进制等于多少?

【代码】

cpp 复制代码
/* 2026-03-19-算法打卡day27
 * 9-蓝桥云课2095-九进制转十进制
 * 算法:没算法
 * Author:郑龙浩
 * Date:2026-03-19
 */

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int result = 0;
    int num = 2022;
    int i = 0;
    while (num) {
        result += (num % 10) * pow(9, i);
        num /= 10;
        i++;
    }
    cout << result;
    return 0;
}

10-蓝桥云课1452-时间显示

题目描述

小蓝要和朋友合作开发一个时间显示的网站。

在服务器上,朋友已经获取了当前的时间,用一个整数表示,值为从 19701970 年 11 月 11 日 00:00:0000:00:00 到当前时刻经过的毫秒数。

现在,小蓝要在客户端显示出这个时间。小蓝不用显示出年月日,只需要显示出时分秒即可,毫秒也不用显示,直接舍去即可。

给定一个用整数表示的时间,请将这个时间对应的时分秒输出。

输入描述

输入一行包含一个整数,表示时间。

输出描述

输出时分秒表示的当前时间,格式形如 HH:MM:SS,其中 HH 表示时,值为 00​​​​ 到 2323​​​​,MM 表示分,值为 00​​​​ 到 5959​​​,SS 表示秒,值为 00​​ 到 5959​。时、分、秒 不足两位时补前导 00。

输入输出样例

示例 1

输入

txt 复制代码
46800999

输出

txt 复制代码
13:00:00
示例 2

输入

txt 复制代码
1618708103123

输出

txt 复制代码
01:08:23

评测用例规模与约定

对于所有评测用例,给定的时间为不超过 10181018 的正整数。

【思路】

注意的点

题目给出的输入是「毫秒数」,不是「秒数」

第一次我根据秒数写的,怎么都不对,才发现题目写的是毫秒

然后就出现了一个挺尴尬的事情,我TM不知道一秒是多少毫秒,呃呃呃,我刚开始按照1秒是100毫秒去算的,答案不对

然后才知道一秒是1000毫秒,这次可给我记住了

然后就是将最后总毫秒数 / 1000,得出秒数

  • 今天总秒数/每小时的秒数得出 到现在的小时数
  • 今天总秒数%每小时秒数得出 不满足1h的剩余秒数
    • 剩余秒数 / 每分钟的秒数,得出现在的分钟数
  • 最后直接将今天总秒数%每分钟秒数,得出最后的秒数

【代码】

cpp 复制代码
/* 2026-03-19-算法打卡day27
 * 10-蓝桥云课1454-时间显示
 * 需要复习,计算出错
 * Author:郑龙浩
 * Date:2026-03-19
 */

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    ll n; cin >> n;
    n = n % (24 * 60 * 60 * 1000); // 取余得到一天内的剩余毫秒数
    n /= 1000; // 毫秒转换为秒
    
    int h, m, s;
    h = n / 3600; // 总秒数 / 每小时的秒数 --> 小时数
    m = n % 3600 / 60; // 总秒数 % 每小时秒数 --> 剩余秒数
                       // 剩余秒数 / 60 --> 分钟数
    s = n % 60; // 总秒数 % 每分钟秒数 --> 秒数
    
    printf("%02d:%02d:%02d", h, m, s); 
    return 0;
}

11-蓝桥云课707-等额本金

【题目】

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

小明从银行贷款 33 万元。约定分 2424 个月,以等额本金方式还款。

这种还款方式就是把贷款额度等分到 2424 个月。每个月除了要还固定的本金外,还要还贷款余额在一个月中产生的利息。

假设月利率是:0.0050.005,即:千分之五。

第一个月,小明要还本金 12501250, 还要还利息:30000∗0.00530000∗0.005,总计 1400.001400.00。

第二个月,本金仍然要还 12501250, 但利息为:(30000−1250)∗0.005(30000−1250)∗0.005 总计 1393.751393.75。

请问:小明在第 1515 个月,应该还款多少(本金和利息的总和)?

请把答案金额四舍五入后,保留两位小数。注意:32.532.5,一定要写为:32.5032.50。

【思路】

注意输出的不是利息,而是本+利即可

【代码】

cpp 复制代码
/* 2026-03-19-算法打卡day27
 * 11-蓝桥云课707-等额本金
 * 算法:没算法
 * Author:郑龙浩
 * Date:2026-03-19
 * 用时:4min
 */

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    printf("%.02f", 1250 + (30000 - 1250 * 14) * 0.005);
    return 0;
}

12-蓝桥云课702-啤酒和饮料

【题目】

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

啤酒每罐 2.32.3 元,饮料每罐 1.91.9 元。小明买了若干啤酒和饮料,一共花了 82.382.3 元。

我们还知道他买的啤酒比饮料的数量少,请你计算他买了几罐啤酒。

【思路】

首先算出nm,表示82.3最多买多少啤酒,多少饮料

需要注意:饮料数量 > 啤酒数量

所以在写循环的时候,啤酒的数量是从饮料数量 + 1 开始遍历的

然后计算出 两者购买时总费用是否为82.3即可

【代码】

cpp 复制代码
/* 2026-03-19-算法打卡day27
 * 12-蓝桥云课702-啤酒和饮料
 * 算法:没算法
 * Author:郑龙浩
 * Date:2026-03-19
 * 用时:3 min 56 s
 */

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int n = 82.3 / 2.3;
    int m = 82.3 / 1.9;
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < m; j++) {
            if (i * 2.3 + j * 1.9 == 82.3) {
                cout << i;
                break;
            }
        }
    }
    return 0;
}

13-蓝桥云课681-立方变自身

【题目】

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

观察下面的现象,某个数字的立方,按位累加仍然等于自身。

txt 复制代码
1^3 = 1 
8^3  = 512    5+1+2=8
17^3 = 4913   4+9+1+3=17
...

请你计算包括 1,8,171,8,17 在内,符合这个性质的正整数一共有多少个?

【思路】

错误1:

刚开始我将题目中的ii,当做了C++中的运算了,没注意题目指的是「立方」,所以刚开始费了点时间,写错了

后来改为 i *i * i就对了
错2:

我刚开始写的时候直接把循环写成了 < INT_MAX

但是运行起来会非常的慢,但是题目直接问 请你计算包括 1,8,171,8,17 在内,符合这个性质的正整数一共有多少个?

并没有说比如1000以内 1000以内的数

所以我断定只有前100或前1000或前10000等有符合这个条件的数字,否则题目会给出范围的

然后我就将for从100到10000尝试,发现从1000开始,无论数字改为多少,答案都是只有6个,所以,我就试了一下是否正确,直接对了

【代码】

cpp 复制代码
/* 2026-03-19-算法打卡day27
 * 13-蓝桥云课681-立方变自身
 * 算法:没算法
 * Author:郑龙浩
 * Date:2026-03-19
 * 用时:10min
 * 原因是:刚开始我将题目中的i^i,当做了C++中的^运算了,没注意题目指的是「立方」,所以刚开始费了点时间,写错了
 */

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int cnt = 0;
    for (int i = 1; i < 10000; i++) {
        int sum = 0;
        int n2 = i * i * i;
        while (n2) {
            sum += n2 % 10;
            n2 /= 10;
        }
        if (i == sum) cnt++;    
    }
    cout << cnt;
    return 0;
}

14-蓝桥云课605-年号字串

【题目】

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

小明用字母 AA 对应数字 11,BB 对应 22,以此类推,用 ZZ 对应 2626。对于 2727 以上的数字,小明用两位或更长位的字符串来对应,例如 AAAA 对应 2727,ABAB 对应 2828,AZAZ 对应 5252,LQLQ 对应 329329。

请问 20192019 对应的字符串是什么?

【思路】

这就是个进制转换的问题,就是计算如何将26进制的数字加起来

我第一次看到并不知道是进制题,所以模拟了一下脑海中的想法:cout << ('L' - 'A' + 1) * 26 + 'Q' - 'A' + 1;,看一下是否等于题目中的329,发现还真是,我就断定是这样了

且进位用的也是26位数,所以进位不能* 10,而是* 26

刚开始我用了两层for,发现不够,然后又加了一层

但是这里要注意,i 表示的是最高位,即百位

  • 十进制的时候,表示百位,要i * 10 * 10
  • 26进制的时候,表示百位,要i * 26 * 26
    所以刚开始,我写的时候,写错了写成了i * 26 * 10,然后我想了想,根据十进制的做法是乘两个十,那么26进制不就是乘两个26吗

然后就做出来了

【代码】

cpp 复制代码
/* 2026-03-19-算法打卡day27
 * 14-蓝桥云课605-年号字串
 * 算法:没算法
 * Author:郑龙浩
 * Date:2026-03-19
 * 用时:9min 08s
 */

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    // cout << ('L' - 'A' + 1) * 26 + 'Q' - 'A' + 1;
    for (char i = 'A'; i <= 'Z'; i++) {
        for (char j = 'A'; j <= 'Z'; j++) {
            for (char k = 'A'; k <= 'Z'; k++) {
                if ((i - 'A' + 1) * 26 * 26 + (j - 'A' + 1) * 26 + k - 'A' + 1 == 2019) {
                    cout << i << j << k;
                    return 0;
                }
            }
        }
    }
    return 0;
}

15-蓝桥云课592-门牌制作

【题目】

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

小蓝要为一条街的住户制作门牌号。

这条街一共有 20202020 位住户,门牌号从 11 到 20202020 编号。

小蓝制作门牌的方法是先制作 00 到 99 这几个数字字符,最后根据需要将字符粘贴到门牌上,例如门牌 1017 需要依次粘贴字符 1、0、1、71、0、1、7,即需要 11 个字符 00,22 个字符 11,11 个字符 77。

请问要制作所有的 11 到 20202020 号门牌,总共需要多少个字符 22?

【思路】

本想用数学直接计算出结果,发现想错了,反而多耗时了4min,暴力反而只用了1 min多点写出来了,下次遇到这种题,如果无法直接算出来,还是选择暴力更节省时间

【代码】

cpp 复制代码
/* 2026-03-19-算法打卡day27
 * 15-蓝桥云课592-门牌制作
 * 算法:没算法
 * Author:郑龙浩
 * Date:2026-03-19
 * 本想用数学直接计算出结果,发现想错了,反而多耗时了4min,暴力反而只用了1 min多点写出来了,下次遇到这种题,如果无法直接算出来,还是选择暴力更节省时间
 */

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    // cout << 1 + (2 * 10) + (20 * 10 + 1) + (202 * 10); // 用了四分钟,没想出来直接算该咋算
    // 用时:1min 41s
    int cnt = 0;
    for (int i = 1; i <= 2020; i++) {
        int n = i;
        while (n) {
            if (n % 10 == 2) cnt++;
            n /= 10;
        }
    }
    cout << cnt;
    return 0;
}

16-蓝桥云课549-扫雷

题目描述

在一个 nn 行 mm 列的方格图上有一些位置有地雷,另外一些位置为空。

请为每个空位置标一个整数,表示周围八个相邻的方格中有多少个地雷。

输入描述

输入的第一行包含两个整数 n,mn,m。

第 22 行到第 n+1n+1 行每行包含 mm 个整数,相邻整数之间用一个空格分隔。如果对应的整数为 00,表示这一格没有地雷。如果对应的整数为 11,表示这一格有地雷。

其中,1≤n,m≤1001≤n,m≤100 分钟后还是在当天。

输出描述

输出 nn 行,每行 mm 个整数,相邻整数之间用空格分隔。

对于没有地雷的方格,输出这格周围的地雷数量。对于有地雷的方格,输出 99。

输入输出样例

示例 1

输入

txt 复制代码
3 4
0 1 0 0
1 0 1 0
0 0 1 0

输出

txt 复制代码
2 9 2 1
9 4 9 2
1 3 9 2

【思路】

【代码】

cpp 复制代码
/* 2026-03-19-算法打卡day27
 * 16-蓝桥云课549-扫雷
 * 算法:没算法
 * Author:郑龙浩
 * Date:2026-03-19
 * 用时:12 min 20 s
 */

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
int direction[8][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}, {1, -1}, {1, 1}, {-1, 1}, {-1, -1}};
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector <vector <int>> nums(n, vector <int> (m, 0));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> nums[i][j];
        }
    }
    vector <vector <int>> results(n, vector <int> (m, 0));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (nums[i][j] == 1) {results[i][j] = 9; continue;}
            for (int x = 0; x < 8; x++) {
                int nextX = i + direction[x][0];
                int nextY = j + direction[x][1];
                if (nextX >= 0 && nextX < n && nextY >= 0 && nextY < m) 
                    if (nums[nextX][nextY] == 1) results[i][j] ++;
            }
        }
    }
    for (auto i: results) {
        for (int j : i) cout << j << ' ';
        cout << '\n';
    }
    return 0;
}

17-蓝桥云课504-单词分析

题目描述

小蓝正在学习一门神奇的语言,这门语言中的单词都是由小写英文字母组 成,有些单词很长,远远超过正常英文单词的长度。小蓝学了很长时间也记不住一些单词,他准备不再完全记忆这些单词,而是根据单词中哪个字母出现得最多来分辨单词。

现在,请你帮助小蓝,给了一个单词后,帮助他找到出现最多的字母和这 个字母出现的次数。

输入描述

输入一行包含一个单词,单词只由小写英文字母组成。

对于所有的评测用例,输入的单词长度不超过 1000。

输出描述

输出两行,第一行包含一个英文字母,表示单词中出现得最多的字母是哪 个。如果有多个字母出现的次数相等,输出字典序最小的那个。

第二行包含一个整数,表示出现得最多的那个字母在单词中出现的次数。

输入输出样例

示例 1

输入

txt 复制代码
lanqiao

输出

txt 复制代码
a
2
示例 2

输入

txt 复制代码
longlonglongistoolong

输出

txt 复制代码
o
6

【思路】

记得在输出字符的时候要转换为char,因为Max + 'a',按照转换规则,会转换为字节大的int而不是字节小的char


【代码】

cpp 复制代码
/* 2026-03-19-算法打卡day27
 * 17-蓝桥云课504-单词分析
 * 算法:没算法
 * Author:郑龙浩
 * Date:2026-03-19
 * 用时:5min
 * 记得在输出字符的时候要转换为char,因为Max + 'a',按照转换规则,会转换为字节大的int而不是字节小的char
 */

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    string s; cin >> s;
    int cnt[26] = {0};
    for (char ch : s) {
        cnt[ch - 'a']++;
    }
    int Max = 0;
    for (int i = 0; i < 26; i++) {
        if (cnt[i] > cnt[Max]) Max = i;
    }
    cout << (char)(Max + 'a') << '\n' << cnt[Max];
    return 0;
}

18-蓝桥云课475-神秘的三位数

题目描述

本题为代码补全填空题,请将题目中给出的源代码补全,并复制到右侧代码框中,选择对应的编译语言(C/Java)后进行提交。若题目中给出的源代码语言不唯一,则只需选择其一进行补全提交即可。复制后需将源代码中填空部分的下划线删掉,填上你的答案。提交后若未能通过,除考虑填空部分出错外,还需注意是否因在复制后有改动非填空部分产生错误。

有这样一个3位数,组成它的3个数字阶乘之和正好等于它本身。即:abc = a! + b! + c!

下面的程序用于搜索这样的3位数。

请仔细阅读代码,并填写划线部分缺失的代码。

源代码

C

c 复制代码
#include <stdio.h>
#include <stdlib.h>

int main()
{
  
int JC[] = {1,1,2,6,24,120,720,5040,40320,362880};
    int i;
    for(i=100; i<1000; i++)
    {
        int sum = 0;
        int x = i;
        while(__________)
        {
            sum += JC[x%10];
            x /= 10;
        }
        if(i==sum) printf("%d\n", i);
    }


  return 0;
}

【代码】

cpp 复制代码
/* 2026-03-19-算法打卡day27
 * 18-蓝桥云课475-神秘的三位数
 * 算法:没算法
 * Author:郑龙浩
 * Date:2026-03-19
 * 用时:1 min
 * 直接填就OK了
 */

#include <stdio.h>
#include <stdlib.h>

int main()
{
  
int JC[] = {1,1,2,6,24,120,720,5040,40320,362880};
    int i;
    for(i=100; i<1000; i++)
    {
        int sum = 0;
        int x = i;
        while(x)
        {
            sum += JC[x%10];
            x /= 10;
        }
        if(i==sum) printf("%d\n", i);
    }


  return 0;
}

19-蓝桥云课468-身份证号校验

本题为代码补全填空题,请将题目中给出的源代码补全,并复制到右侧代码框中,选择对应的编译语言(C/Java)后进行提交。若题目中给出的源代码语言不唯一,则只需选择其一进行补全提交即可。复制后需将源代码中填空部分的下划线删掉,填上你的答案。提交后若未能通过,除考虑填空部分出错外,还需注意是否因在复制后有改动非填空部分产生错误。

如果让你设计个程序,用什么变量保存身份证号码呢?长整数可以吗?不可以!

因为有人的身份证最后一位是 "X"。

实际上,除了最后一位的 X,不会出现其它字母!

身份证号码 18 位 = 17 位 + 校验码

校验码的计算过程:

例如:身份证前 17 位 = ABCDEFGHIJKLMNOPQ

A~Q 每位数字乘以权值求和(每位数字和它对应的"权"相乘后累加)。

17 位对应的权值分别是:

7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2

求出的总和再对 11 求模

然后按下表映射:

余数: 0 1 2 3 4 5 6 7 8 9 10

校验码: 1 0 X 9 8 7 6 5 4 3 2

下面的代码实现了校验过程,输入串为身份证前17位,打印出校验码。

请仔细阅读代码,并填写划线部分缺失的代码。

源代码

C

c 复制代码
#include <stdio.h>
#include <stdlib.h>
char verifyCode(char* s)
{
    static int weight[] = {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
    static char map[] = {'1','0','X','9','8','7','6','5','4','3','2'};

    int sum = 0;
    for(int i=0; i<17; i++)
    {
        sum += (______________) * weight[i];  // 填空
    }

    return map[______________];  // 填空
    
}

int main(int argc, char* argv[])
{
    printf("%c\n", verifyCode("32011119610215381"));
    printf("%c\n", verifyCode("42900819801018236"));
    return 0;
}

【代码】

cpp 复制代码
/* 2026-03-19-算法打卡day27
 * 19-蓝桥云课468-身份证号校验
 * 算法:没算法
 * Author:郑龙浩
 * Date:2026-03-19
 * 填空题 用时:4min
 */

#include <stdio.h>
#include <stdlib.h>
char verifyCode(char* s)
{
    static int weight[] = {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
    static char map[] = {'1','0','X','9','8','7','6','5','4','3','2'};

    int sum = 0;
    for(int i=0; i<17; i++)
    {
        sum += (s[i] - '0') * weight[i];  // 填空
    }

    return map[sum % 11];  // 填空
    
}

int main(int argc, char* argv[])
{
    printf("%c\n", verifyCode("32011119610215381"));
    printf("%c\n", verifyCode("42900819801018236"));
    return 0;
}

20-蓝桥云课467-干支纪年(没细读题,需要复习)

本题为代码补全填空题,请将题目中给出的源代码补全,并复制到右侧代码框中,选择对应的编译语言(C/Java)后进行提交。若题目中给出的源代码语言不唯一,则只需选择其一进行补全提交即可。复制后需将源代码中填空部分的下划线删掉,填上你的答案。提交后若未能通过,除考虑填空部分出错外,还需注意是否因在复制后有改动非填空部分产生错误。

在我国古代和近代,一直采用干支法纪年。它采用 10 天干和 12 地支配合,一个循环周期为 60 年。

10 天干是:甲,乙,丙,丁,戊,己,庚,辛,壬,癸;

12 地支是:子,丑,寅,卯,辰,巳,午,未,申,酉,戌,亥。

如果某年是甲子,下一年就是乙丑,再下是丙寅,...癸酉,甲戌,乙亥,丙子,...

总之天干、地址都是循环使用,两两配对。

今年(2012)是壬辰年,1911 年辛亥革命

下面的代码根据公历年份输出相应的干支法纪年。已知最近的甲子年是1984 年。

请仔细阅读代码,并填写划线部分缺失的代码。

源代码

C

c 复制代码
#include <stdio.h>
#include <stdlib.h>
void f(int year)
{
    char* x[] = {"甲","乙","丙","丁","戊","己","庚","辛","壬","癸"};
    char* y[] = {"子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"};
    
    int n = year - 1984;
    
    while(n<0) n += 60;

    printf("%s%s\n", x[_______], y[_______]);
}

int main(int argc, char* argv[])
{
    f(1911);
    f(1970);
    f(2012);
    return 0;
}

【思路】

这是一个双周期循环问题:

  • 以1984年(甲子年)为基准,计算目标年份的偏移年数n
  • 天干10年一循环,用n % 10确定天干位置
  • 地支12年一循环,用n % 12确定地支位置
  • 60是10和12的最小公倍数,形成一个完整的甲子循环
  • 取模运算得到的是"在循环中的位置",而不是循环的圈数

我刚开始想的是都填n % 12,但是x数组会越界

后来我发现我理解错了

我起初理解的天干地支计算方式为

地支走到底,从头来的时候,天干就走一下,以此类推

所以之前我还纳闷,为什么60而不是120,哈哈哈,题目没仔细看

其实是

天干和地支共同往后走

还是没仔细读题

【代码】

21-蓝桥云课456-三部排序(需要复习)

三向切分

题目描述

本题为代码补全填空题,请将题目中给出的源代码补全,并复制到右侧代码框中,选择对应的编译语言(C/Java)后进行提交。若题目中给出的源代码语言不唯一,则只需选择其一进行补全提交即可。复制后需将源代码中填空部分的下划线删掉,填上你的答案。提交后若未能通过,除考虑填空部分出错外,还需注意是否因在复制后有改动非填空部分产生错误。

一般的排序有许多经典算法,如快速排序、希尔排序等。

但实际应用时,经常会或多或少有一些特殊的要求。我们没必要套用那些经典算法,可以根据实际情况建立更好的解法。

比如,对一个整型数组中的数字进行分类排序:

使得负数都靠左端,正数都靠右端,0 在中部。注意问题的特点是:负数区域和正数区域内并不要求有序。可以利用这个特点通过 1 次线性扫描就结束战斗!!

以下的程序实现了该目标。

其中 xx 指向待排序的整型数组,lenlen 是数组的长度。

请分析代码逻辑,并推测划线处的代码。

源代码

C

c 复制代码
#include <stdio.h>

void show(int* x, int len)
{
    int i;
    for(i=0; i<len; i++)
    {
        printf("%d,",x[i]);
    }
    
    printf("\n");
}

void sort3p(int* x, int len)
{
    int p = 0;
    int left = 0;
    int right = len-1;
    
    while(p<=right){
        if(x[p]<0){
            int t = x[left];
            x[left] = x[p];
            x[p] = t;
            left++;
            p++;
        }
        else if(x[p]>0){
            int t = x[right];
            x[right] = x[p];
            x[p] = t;
            right--;
            //p++;                
        }
        else{
            _______________;
        }
    }
    
    show(x, len);
}

int main()
{
    int a[] = {-1,0,1,-2,0,2,-3,0,0,3,-4,-5,4,-6,0,5,6};
    int b[] = {-1,0,-1,-2,0,-2,-3,0,0,-3,-4,-5,-4,-6,0,-5,-6};
    int c[] = {1,0,1,2,0,2,3,0,0,3,4,5,4,6,0,5,6};
    
    sort3p(a,sizeof(a)/sizeof(int));
    sort3p(b,sizeof(b)/sizeof(int));
    sort3p(c,sizeof(c)/sizeof(int));
        
    return 0;
}

【思路】

没做出来,不会做,我没想明白这个代码到底是什么意思

【AI解答】

算法:荷兰国旗三向切分算法

思路

三个指针划分三个区域:

  • left左侧:已处理负数

  • leftp-1:已处理0

  • pright:未处理区域

  • right右侧:已处理正数

处理规则

  1. 遇到负数:与left交换,left++p++

  2. 遇到0:p++

  3. 遇到正数:与right交换,right--

为何负数交换后p++

因为leftp-1区间内全是0 (循环不变式),交换后p指向0,而0已在正确位置,可直接跳过。

我的疑惑 :为什么left ~ p - 1都是0

因为在p是0的时候,p++,所以这就导致了left ~ p-1之间的所有元素都是0,所以当x[p]是负数的时候,x与left交换,其实是将元素0交换到了p的位置,所以p++直接跳到

【代码】

cpp 复制代码
/* 2026-03-19-算法打卡day27
 * 10-蓝桥云课1454-时间显示
 * 算法:三向切分
 * Author:郑龙浩
 * Date:2026-03-19
 * 用时:10min
 */

#include <stdio.h>

void show(int* x, int len)
{
    int i;
    for(i=0; i<len; i++)
    {
        printf("%d,",x[i]);
    }
    
    printf("\n");
}

void sort3p(int* x, int len)
{
    int p = 0;          // 当前遍历指针
    int left = 0;       // 负数区右边界,left左侧全是负数
    int right = len-1;  // 正数区左边界,right右侧全是正数
    
    while(p<=right){
        if(x[p]<0){     // 当前是负数,放到负数区
            int t = x[left];
            x[left] = x[p];
            x[p] = t;
            left++;
            p++;         // 因为lefr ~ p - 1之间的数字都是0,所以将left交换到p后,p位置就是0了,直接跳过即可
        }
        else if(x[p]>0){ // 当前是正数,放到正数区
            int t = x[right];
            x[right] = x[p];
            x[p] = t;
            right--;     // 交换后p的位置是之前没遇过的,也不知道是不是0,所以要处理的
        }
        else{           // 当前是0,直接跳过,让left ~ p-1之间保持都是0
            p++;
        }
    }
    
    show(x, len);
}

int main()
{
    int a[] = {-1,0,1,-2,0,2,-3,0,0,3,-4,-5,4,-6,0,5,6};
    int b[] = {-1,0,-1,-2,0,-2,-3,0,0,-3,-4,-5,-4,-6,0,-5,-6};
    int c[] = {1,0,1,2,0,2,3,0,0,3,4,5,4,6,0,5,6};
    
    sort3p(a,sizeof(a)/sizeof(int));
    sort3p(b,sizeof(b)/sizeof(int));
    sort3p(c,sizeof(c)/sizeof(int));
        
    return 0;
}

22-蓝桥云课436-九数组分数(需要复习)

题目描述

本题为代码补全填空题,请将题目中给出的源代码补全,并复制到右侧代码框中,选择对应的编译语言(C/Java)后进行提交。若题目中给出的源代码语言不唯一,则只需选择其一进行补全提交即可。复制后需将源代码中填空部分的下划线删掉,填上你的答案。提交后若未能通过,除考虑填空部分出错外,还需注意是否因在复制后有改动非填空部分产生错误。

1,2,3...9 这九个数字组成一个分数,其值恰好为1/3,如何组法?

下面的程序实现了该功能,请填写划线部分缺失的代码。

源代码

C

c 复制代码
#include <stdio.h>
void test(int x[])
{
    int a = x[0]*1000 + x[1]*100 + x[2]*10 + x[3];
    int b = x[4]*10000 + x[5]*1000 + x[6]*100 + x[7]*10 + x[8];
    
    if(a*3==b) printf("%d/%d\n", a, b);
}
void f(int x[], int k)
{
    int i,t;
    if(k>=9){
        test(x);
        return;
    }
    
    for(i=k; i<9; i++){
        {t=x[k]; x[k]=x[i]; x[i]=t;}
        f(x,k+1);
        _________________
    }
}
int main()
{
    int x[] = {1,2,3,4,5,6,7,8,9};
    f(x,0);    
    return 0;
}

【思路】

这是个回溯算法,当前位置更换后,后面元素全部尝试完后,要再换回来,避免数组顺序出错

对于回溯,我依然没有很理解,这个一直是我心里的一个很大坎,然后因为回溯不理解,DP的很多题也不理解,哎,难受

【代码】

cpp 复制代码
/* 2026-03-19-算法打卡day27
 * 22-蓝桥云课436-九数组分数
 * 算法:回溯算法
 * Author:郑龙浩
 * Date:2026-03-19
 * 用时:4min
 */

#include <stdio.h>
void test(int x[])
{
    int a = x[0]*1000 + x[1]*100 + x[2]*10 + x[3];
    int b = x[4]*10000 + x[5]*1000 + x[6]*100 + x[7]*10 + x[8];
    
    if(a*3==b) printf("%d/%d\n", a, b);
}
void f(int x[], int k)
{
    int i,t;
    if(k>=9){
        test(x);
        return;
    }
    
    for(i=k; i<9; i++){
        {t=x[k]; x[k]=x[i]; x[i]=t;}
        f(x,k+1);
        t=x[k]; x[k]=x[i]; x[i]=t; // 回溯
    }
}
int main()
{
    int x[] = {1,2,3,4,5,6,7,8,9};
    f(x,0);    
    return 0;
}

23-蓝桥云课422-最大公共子串(需要复习)

题目描述

本题为代码补全填空题,请将题目中给出的源代码补全,并复制到右侧代码框中,选择对应的编译语言(C/Java)后进行提交。若题目中给出的源代码语言不唯一,则只需选择其一进行补全提交即可。复制后需将源代码中填空部分的下划线删掉,填上你的答案。提交后若未能通过,除考虑填空部分出错外,还需注意是否因在复制后有改动非填空部分产生错误。

最大公共子串长度问题就是: 求两个串的所有子串中能够匹配上的最大长度是多少。

比如:"abcdkkk" 和 "baabcdadabc", 可以找到的最长的公共子串是"abcd",所以最大公共子串长度为 4。

下面的程序是采用矩阵法进行求解的,这对串的规模不大的情况还是比较有效的解法。

请分析该解法的思路,并补全划线部分缺失的代码。

源代码

C

c 复制代码
#include <stdio.h>
#include <string.h>

#define N 256
int f(const char* s1, const char* s2)
{
    int a[N][N];
    int len1 = strlen(s1);
    int len2 = strlen(s2);
    int i,j;
    
    memset(a,0,sizeof(int)*N*N);
    int max = 0;
    for(i=1; i<=len1; i++){
        for(j=1; j<=len2; j++){
            if(s1[i-1]==s2[j-1]) {
                a[i][j] = __________________________; 
                if(a[i][j] > max) max = a[i][j];
            }
        }
    }
    
    return max;
}

int main()
{
    printf("%d\n", f("abcdkkk", "baabcdadabc"));
    printf("%d\n", f("aaakkkabababa", "baabababcdadabc"));
    printf("%d\n", f("abccbaacbcca", "ccccbbbbbaaaa"));    
    printf("%d\n", f("abcd", "xyz"));
    printf("%d\n", f("ab", "ab"));
    return 0;
}

【思路】

DP 算法
dp[i][j]表示:以字符串 s1 的第 i-1 个字符结尾,同时以字符串 s2 的第 j-1 个字符结尾的最长公共子串的长度。

【代码】

cpp 复制代码
/* 2026-03-19-算法打卡day27
 * 23-蓝桥云课422-最大公共子串
 * 算法:动态规划
 * Author:郑龙浩
 * Date:2026-03-19
 */

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
#include <stdio.h>
#include <string.h>

#define N 256
int f(const char* s1, const char* s2)
{
    int a[N][N];
    int len1 = strlen(s1);
    int len2 = strlen(s2);
    int i,j;
    
    memset(a,0,sizeof(int)*N*N);
    int max = 0;
    for(i=1; i<=len1; i++){
        for(j=1; j<=len2; j++){
            if(s1[i-1]==s2[j-1]) {
                a[i][j] = a[i-1][j-1] + 1;
                if(a[i][j] > max) max = a[i][j];
            }
        }
    }
    
    return max;
}

int main()
{
    printf("%d\n", f("abcdkkk", "baabcdadabc"));
    printf("%d\n", f("aaakkkabababa", "baabababcdadabc"));
    printf("%d\n", f("abccbaacbcca", "ccccbbbbbaaaa"));    
    printf("%d\n", f("abcd", "xyz"));
    printf("%d\n", f("ab", "ab"));
    return 0;
}
相关推荐
罗湖老棍子2 小时前
滑动窗口与双调队列:幕布覆盖问题(定右缩左满分板子)改编自LeetCode 1438
算法·滑动窗口·单调队列
CoovallyAIHub2 小时前
ICLR 2026 | MedAgent-Pro:用 Agent 工作流模拟临床医生的循证诊断过程
深度学习·算法·计算机视觉
实心儿儿2 小时前
算法7:两个数组的交集
算法·leetcode·职场和发展
我可能是个假开发2 小时前
算法-回溯
算法
WolfGang0073212 小时前
代码随想录算法训练营 Day14 | 二叉树 part04
数据结构·算法
爱丽_2 小时前
GC 怎么判定“该回收谁”:GC Roots、可达性分析、四种引用与回收算法
java·jvm·算法
dfafadfadfafa2 小时前
嵌入式C++安全编码
开发语言·c++·算法
仍然.2 小时前
算法题目---前缀和
算法
计算机安禾2 小时前
【C语言程序设计】第34篇:文件的概念与文件指针
c语言·开发语言·数据结构·c++·算法·visual studio code·visual studio