2022年蓝桥杯省赛B组题目解析(C/C++)


目录
  • 2022年蓝桥杯省赛B组题目解析(C/C++)
    • 试题 A: 九进制转十进制
    • 试题 B: 顺子日期
    • 试题 C: 刷题统计
    • 试题 D: 修剪灌木
    • 试题 E: X 进制减法
    • 试题 F: 统计子矩阵
    • 试题 G: 积木画
    • 试题 H: 扫雷
    • 试题 I: 李白打酒加强版
    • 试题 J: 砍竹子

2022年蓝桥杯省赛B组题目解析(C/C++)

oj:https://www.dotcpp.com/oj/train/1026/

试题 A: 九进制转十进制

本题总分:5 分

【问题描述】
九进制正整数 (2022)9 转换成十进制等于多少?

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

  • 答案:1478
#include
int main(){
    int n = 2022;
    int a=0, base=1;
    while(n){
        a += n%10*base;
        base *= 9;
        n /= 10;
    }
    printf("%d\n", a);
    return 0;
}

试题 B: 顺子日期

本题总分:5 分

【问题描述】
小明特别喜欢顺子。顺子指的就是连续的三个数字:123、456 等。
顺子日期指的就是在日期的 yyyymmdd 表示法中,存在任意连续的三位数是一个顺子的日期。
例如 20220123 就是一个顺子日期,因为它出现了一个顺子:123;
而 20221023 则不是一个顺子日期,它一个顺子也没有。小明想知道在整个 2022年份中,一共有多少个顺子日期。

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

  • 答案:14
#include
bool check(int num){
    int temp=num, cnt=1, maxv=num%10;
    while(temp){
        temp/=10;
        if(cnt==3) return 1;
        if(maxv-temp%10==1) maxv=temp%10, cnt++;
        else maxv=temp%10, cnt=1;
    }
    return 0;
}
int main(){
    int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
    int year=2022,ans=0;
    if(year%400==0 || year%4==0&&year%100!=0) day[2]++;
    for(int m=1; m<=12; m++){
        for(int d=1; d<=day[m]; d++){
            int temp=year*10000+m*100+d;
            printf("%d\n", temp);
            if(check(temp)) {
                ans++;
                printf("------- ans = %d\n", ans);// 输出查看
            }
        }
    }
    printf("%d\n", ans);
    return 0;
}

试题 C: 刷题统计

时间限制: 1.0s 内存限制: 256.0MB 本题总分:10 分

【问题描述】
小明决定从下周一开始努力刷题准备蓝桥杯竞赛。
他计划周一至周五每天做 a 道题目,周六和周日每天做 b 道题目。
请你帮小明计算,按照计划他将在第几天实现做题数大于等于 n 题?

【输入格式】输入一行包含三个整数 a, b 和 n.
【输出格式】输出一个整数代表天数。
【样例输入】10 20 99
【样例输出】8

【评测用例规模与约定】
对于 50% 的评测用例,1 ≤ a, b, n ≤ 1e7.
对于 100% 的评测用例,1 ≤ a, b, n ≤ 1e19.

  • 数据较大注意范围
#include
typedef long long ll;
ll test1(ll a,ll b,ll n){ // 枚举天数 50分
    for(ll x=1; ; x++){
        ll temp = x/7*5*a + x/7*2*b;
        if(x%7<=5) temp += a*(x%7);
        else temp += a*5+b*(x%7-5);
        if(temp>=n) return x;
    }
}
ll test2(ll a,ll b,ll n){ // 模拟 50分
    ll ans=0, x=1;
    while(n>0){
        if(x>7) x=1;
        if(x<=5) n-=a;
        else if(x<=7) n-=b;
        ans++, x++;
    }
    return ans;
}
ll test3(ll a,ll b,ll n){ // 正解
    ll x = n/(5*a+2*b),ans=0; // 已完成周数
    ll temp = n%(5*a+2*b);    // 剩余题数在一周内可完成
    for(int i=1; i<=7; i++){
        if(temp>0 && i<=5) temp-=a, ans++;
        if(temp>0 && i>=6) temp-=b, ans++;
    }
    return x*7+ans;
}
int main(){
    ll a,b,n,ans=1; scanf("%lld%lld%lld",&a,&b,&n);
    printf("%lld\n", test3(a,b,n));
    return 0;
}

试题 D: 修剪灌木

时间限制: 1.0s 内存限制: 256.0MB 本题总分:10 分

【问题描述】
爱丽丝要完成一项修剪灌木的工作。
有 N 棵灌木整齐的从左到右排成一排。
爱丽丝在每天傍晚会修剪一棵灌木,让灌木的高度变为 0 厘米。
爱丽丝修剪灌木的顺序是从最左侧的灌木开始,每天向右修剪一棵灌木。
当修剪了最右侧的灌木后,她会调转方向,下一天开始向左修剪灌木。
直到修剪了最左的灌木后再次调转方向。然后如此循环往复。
灌木每天从早上到傍晚会长高 1 厘米,而其余时间不会长高。
在第一天的早晨,所有灌木的高度都是 0 厘米。
爱丽丝想知道每棵灌木最高长到多高。

【输入格式】一个正整数 N ,含义如题面所述。
【输出格式】输出 N 行,每行一个整数,第行表示从左到右第 i 棵树最高能长到多高。
【样例输入】3
【样例输出】

4
2
4

【评测用例规模与约定】
对于 30% 的数据,N ≤ 10.
对于 100% 的数据,1 < N ≤ 10000.

  • 多画多思考,当前为第 i 棵树的位置,其最高为 max(左边回路需要天数,右边回路需要天数);
#include
int max(int a,int b){
    return a>b ? a:b;
}
int main(){
    int n; scanf("%d", &n);
    for(int i=1; i<=n; i++){
        printf("%d\n",2*max(n-i, i-1));
    }
    return 0;
}

试题 E: X 进制减法

时间限制: 1.0s 内存限制: 256.0MB 本题总分:15 分

【问题描述】
进制规定了数字在数位上逢几进一。
X 进制是一种很神奇的进制,因为其每一数位的进制并不固定!
例如说某种 X 进制数,最低数位为二进制,第二数位为十进制,第三数位为八进制,则 X 进制数 321 转换为十进制数为 65。

现在有两个 X 进制表示的整数 A 和 B,但是其具体每一数位的进制还不确定,
只知道 A 和 B 是同一进制规则,且每一数位最高为 N 进制,最低为二进制。
请你算出 A ? B 的结果最小可能是多少。
请注意,你需要保证 A 和 B 在 X 进制下都是合法的,即每一数位上的数字要小于其进制。

【输入格式】
第一行一个正整数 N,含义如题面所述。
第二行一个正整数 Ma,表示 X 进制数 A 的位数。
第三行 Ma 个用空格分开的整数,表示 X 进制数 A 按从高位到低位顺序各个数位上的数字在十进制下的表示。
第四行一个正整数 Mb,表示 X 进制数 B 的位数。
第五行 Mb 个用空格分开的整数,表示 X 进制数 B 按从高位到低位顺序各个数位上的数字在十进制下的表示。
请注意,输入中的所有数字都是十进制的。

【输出格式】
输出一行一个整数,表示 X 进制数 A - B 的结果的最小可能值转换为十进制后再模 1000000007 的结果。

【样例输入】

11
3
10 4 0
3
1 2 0

【样例输出】94

【样例说明】
当进制为:最低位 2 进制,第二数位 5 进制,第三数位 11 进制时,减法得到的差最小。
此时 A 在十进制下是 108,B 在十进制下是 14,差值是 94。

【评测用例规模与约定】
对于 30% 的数据,N ≤ 10; Ma, Mb ≤ 8.
对于 100% 的数据,2 ≤ N ≤ 1000; 1 ≤ Ma, Mb ≤ 100000; A ≥ B.

试题 F: 统计子矩阵

时间限制: 1.0s 内存限制: 256.0MB 本题总分:15 分

【问题描述】
给定一个 N × M 的矩阵 A,请你统计有多少个子矩阵 (最小 1 × 1,最大N × M) 满足子矩阵中所有数的和不超过给定的整数 K?

【输入格式】第一行包含三个整数 N, M 和 K.之后 N 行每行包含 M 个整数,代表矩阵 A.
【输出格式】一个整数代表答案。
【样例输入】

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

【样例输出】19

【样例说明】
满足条件的子矩阵一共有 19,包含:
大小为 1 × 1 的有 10 个。
大小为 1 × 2 的有 3 个。
大小为 1 × 3 的有 2 个。
大小为 1 × 4 的有 1 个。
大小为 2 × 1 的有 3 个。

【评测用例规模与约定】
对于 30% 的数据,N, M ≤ 20.
对于 70% 的数据,N, M ≤ 100.
对于 100% 的数据,1 ≤ N, M ≤ 500; 0 ≤ Ai j ≤ 1000; 1 ≤ K ≤ 250000000.

试题 G: 积木画

时间限制: 1.0s 内存限制: 256.0MB 本题总分:20 分

【问题描述】
小明最近迷上了积木画,有这么两种类型的积木,分别为 I 型(大小为 2个单位面积)和 L 型(大小为 3 个单位面积):
同时,小明有一块面积大小为 2 × N 的画布,画布由 2 × N 个 1 × 1 区域构成。
小明需要用以上两种积木将画布拼满,他想知道总共有多少种不同的方式?
积木可以任意旋转,且画布的方向固定。

【输入格式】输入一个整数 N,表示画布大小。
【输出格式】输出一个整数表示答案。由于答案可能很大,所以输出其对 1000000007 取模后的值
【样例输入】3
【样例输出】5

试题 H: 扫雷

时间限制: 1.0s 内存限制: 256.0MB 本题总分:20 分

【问题描述】
小明最近迷上了一款名为《扫雷》的游戏。
其中有一个关卡的任务如下,在一个二维平面上放置着 n 个炸雷,
第 i 个炸雷 (xi, yi,ri) 表示在坐标 (xi, yi) 处存在一个炸雷,
它的爆炸范围是以半径为 ri 的一个圆。为了顺利通过这片土地,需要玩家进行排雷。

玩家可以发射 m 个排雷火箭,小明已经规划好了每个排雷火箭的发射方向,
第 j 个排雷火箭 (xj, yj, rj) 表示这个排雷火箭将会在(xj, yj) 处爆炸,
它的爆炸范围是以半径为 rj 的一个圆,在其爆炸范围内的炸雷会被引爆。
同时,当炸雷被引爆时,在其爆炸范围内的炸雷也会被引爆。

现在小明想知道他这次共引爆了几颗炸雷?
你可以把炸雷和排雷火箭都视为平面上的一个点。
一个点处可以存在多个炸雷和排雷火箭。
当炸雷位于爆炸范围的边界上时也会被引爆。

【输入格式】
输入的第一行包含两个整数 n、m.
接下来的 n 行,每行三个整数 xi, yi, ri,表示一个炸雷的信息。
再接下来的 m 行,每行三个整数 xj, yj, rj,表示一个排雷火箭的信息。

【输出格式】输出一个整数表示答案。
【样例输入】

2 1
2 2 4
4 4 2
0 0 5

【样例输出】2

试题 I: 李白打酒加强版

时间限制: 1.0s 内存限制: 256.0MB 本题总分:25 分

【问题描述】
话说大诗人李白,一生好饮。幸好他从不开车。
一天,他提着酒壶,从家里出来,酒壶中有酒 2 斗。他边走边唱:
无事街上走,提壶去打酒。
逢店加一倍,遇花喝一斗。
这一路上,他一共遇到店 N 次,遇到花 M 次。
已知最后一次遇到的是花,他正好把酒喝光了。
请你计算李白这一路遇到店和花的顺序,有多少种不同的可能?
注意:壶里没酒 ( 0 斗) 时遇店是合法的,加倍后还是没酒;
但是没酒时遇花是不合法的。

【输入格式】第一行包含两个整数 N 和 M.
【输出格式】输出一个整数表示答案。由于答案可能很大,输出模 1000000007 的结果。
【样例输入】5 10
【样例输出】14

【评测用例规模与约定】
对于 40% 的评测用例:1 ≤ N, M ≤ 10。
对于 100% 的评测用例:1 ≤ N, M ≤ 100。

试题 J: 砍竹子

时间限制: 1.0s 内存限制: 256.0MB 本题总分:25 分

【问题描述】
这天,小明在砍竹子,他面前有 n 棵竹子排成一排,一开始第 i 棵竹子的高度为 hi.
他觉得一棵一棵砍太慢了,决定使用魔法来砍竹子。
魔法可以对连续的一段相同高度的竹子使用,假设这一段竹子的高度为 H,
那么使用一次魔法可以把这一段竹子的高度都变为 sqrt( ?H/2? + 1),其中 ?x? 表示对 x 向下取整。
小明想知道他最少使用多少次魔法可以让所有的竹子的高度都变为 1。

【输入格式】
第一行为一个正整数 n,表示竹子的棵数。
第二行共 n 个空格分开的正整数 hi,表示每棵竹子的高度。

【输出格式】一个整数表示答案。
【样例输入】

6
2 1 4 2 6 7

【样例输出】5