2021年第十二届蓝桥杯决赛B组题解(C/C++)

目录

结果填空题

试题A:宽带(本题总分:5 分)

【问题描述】

【答案提交】25

 【代码】

试题B:纯质数(本题总分:5 分)

【问题描述】

【答案提交】1903

 【代码】 

试题C: 完全日期(本题总分:10 分)

【问题描述】

【答案提交】977

试题D: 最小权值(本题总分:10 分)

【问题描述】

【答案提交】

程序设计题

试题E: 大写(时间限制: 1.0s 内存限制: 256.0MB 本题总分:15 分)

【问题描述】

试题F: 123(时间限制: 1.0s 内存限制: 256.0MB 本题总分:15 分)

【问题描述】

试题G: 异或变换(时间限制: 1.0s 内存限制: 256.0MB 本题总分:20 分)

【问题描述】

试题I: 试翻转括号序列(时间限制: 2.0s 内存限制: 512.0MB 本题总分:25 分)

【问题描述】

【输入格式】

【输出格式】

【样例输入】

【样例输出】

【评测用例规模与约定】

试题J: 异或三角(时间限制: 1.0s 内存限制: 256.0MB 本题总分:25 分)

【问题描述】

【输入格式】

【输出格式】

【样例输入】

【样例输出】

【评测用例规模与约定】


结果填空题

试题A:宽带(本题总分:5 分)

【问题描述】

小蓝家的网络带宽是 200 Mbps,请问,使用小蓝家的网络理论上每秒钟最 多可以从网上下载多少 MB 的内容。

【答案提交】25

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

 【代码】

#include <iostream>
using namespace std;

int main()
{
    cout<<200/8;
    return 0;
}

试题B:纯质数(本题总分:5 分)

【问题描述】

如果一个正整数只有 1 和它本身两个约数,则称为一个质数(又称素数)。 前几个质数是:2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, · · · 。 如果一个质数的所有十进制数位都是质数,我们称它为纯质数。例如:2, 3, 5, 7, 23, 37 都是纯质数,而 11, 13, 17, 19, 29, 31 不是纯质数。当然 1, 4, 35 也不是纯质数。 请问,在 1 到 20210605 中,有多少个纯质数?

【答案提交】1903

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

 【代码】 

#include <iostream>
using namespace std;

bool isZhiShu(int num)
{
    int temp = num;
    while(temp)
    {
        int t = temp%10;
        if(t!=2 && t!=3 && t!=5 && t!=7){return false;}
        temp /= 10;
    }

    for(int i=2;i<num;i++)
    {
        if(num%i==0){return false;}
    }
    
    return true;
}

int main()
{
    int result = 0;
    for(int i=2;i<=20210605;i++)
    {
        if(isZhiShu(i))
        {
            result++;
        }
    }
    cout<<result;
    return 0;
}

试题C: 完全日期(本题总分:10 分)

【问题描述】

如果一个日期中年月日的各位数字之和是完全平方数,则称为一个完全日 期。 例如:2021 年 6 月 5 日的各位数字之和为 2 + 0 + 2 + 1 + 6 + 5 = 16,而 16 是一个完全平方数,它是 4 的平方。所以 2021 年 6 月 5 日是一个完全日期。 例如:2021 年 6 月 23 日的各位数字之和为 2 + 0 + 2 + 1 + 6 + 2 + 3 = 16, 是一个完全平方数。所以 2021 年 6 月 23 日也是一个完全日期。 请问,从 2001 年 1 月 1 日到 2021 年 12 月 31 日中,一共有多少个完全日 期?

【答案提交】977

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

#include <iostream>
using namespace std;

int y, m, d;
int dom[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
unordered_map<int,int> c;

int sum(int num)
{
    int result = 0;
    while(num)
    {
        result += num%10;
        num /= 10;
    }
    return result;
}

int main()
{
    for(int i=0;i<10;i++){c[i*i]=1;}

    int result = 0;
    y=2001;m=1;d=1;

    while(true)
    {
        if(c[ sum(y)+sum(m)+sum(d) ]==1){result++;}

        if(y==2021 && m==12 && d==31){break;}

        if(++d>dom[m])
        {
            d=1;
            if(++m>12)
            {
                m = 1;
                y++;
                if((y%4==0 && y%100!=0)||y%400==0)
                    {dom[2]=29;}
                else
                    {dom[2]=28;}
            }
        }
    }

    cout<<result;
    return 0;
}

试题D: 最小权值(本题总分:10 分)

【问题描述】

对于一棵有根二叉树 T,小蓝定义这棵树中结点的权值 W(T) 如下: 空子树的权值为 0。 如果一个结点 v 有左子树 L, 右子树 R,分别有 C(L) 和 C(R) 个结点,则 W(v) = 1 + 2W(L) + 3W(R) + (C(L)) 2 C(R)。 树的权值定义为树的根结点的权值。 小蓝想知道,对于一棵有 2021 个结点的二叉树,树的权值最小可能是多少?

【答案提交】

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

程序设计题

试题E: 大写(时间限制: 1.0s 内存限制: 256.0MB 本题总分:15 分)

【问题描述】

给定一个只包含大写字母和小写字母的字符串,请将其中所有的小写字母 转换成大写字母后将字符串输出。

【输入格式】 输入一行包含一个字符串。

【输出格式】 输出转换成大写后的字符串。

【样例输入 1】 LanQiao

【样例输出 1】 LANQIAO

【评测用例规模与约定】 对于所有评测用例,字符串的长度不超过 100。

试题F: 123(时间限制: 1.0s 内存限制: 256.0MB 本题总分:15 分)

【问题描述】

小蓝发现了一个有趣的数列,这个数列的前几项如下: 1, 1, 2, 1, 2, 3, 1, 2, 3, 4, ... 小蓝发现,这个数列前 1 项是整数 1,接下来 2 项是整数 1 至 2,接下来 3 项是整数 1 至 3,接下来 4 项是整数 1 至 4,依次类推。 小蓝想知道,这个数列中,连续一段的和是多少。 【输入格式】 输入的第一行包含一个整数 T,表示询问的个数。 接下来 T 行,每行包含一组询问,其中第 i 行包含两个整数 li 和 ri,表示 询问数列中第 li 个数到第 ri 个数的和。

【输出格式】

输出 T 行,每行包含一个整数表示对应询问的答案。

【样例输入】

3

1 1

1 3

5 8

【样例输出】

1

4

【评测用例规模与约定】

对于 10% 的评测用例,1 ≤ T ≤ 30, 1 ≤ li ≤ ri ≤ 100。

对于 20% 的评测用例,1 ≤ T ≤ 100, 1 ≤ li ≤ ri ≤ 1000。

对于 40% 的评测用例,1 ≤ T ≤ 1000, 1 ≤ li ≤ ri ≤ 106。

对于 70% 的评测用例,1 ≤ T ≤ 10000, 1 ≤ li ≤ ri ≤ 109。

对于 80% 的评测用例,1 ≤ T ≤ 1000, 1 ≤ li ≤ ri ≤ 1012。

对于 90% 的评测用例,1 ≤ T ≤ 10000, 1 ≤ li ≤ ri ≤ 1012。

对于所有评测用例,1 ≤ T ≤ 100000, 1 ≤ li ≤ ri ≤ 1012。

试题G: 异或变换(时间限制: 1.0s 内存限制: 256.0MB 本题总分:20 分)

【问题描述】

小蓝有一个 01 串 s = s1 s2 s3 · · · sn。 以后每个时刻,小蓝要对这个 01 串进行一次变换。每次变换的规则相同。 对于 01 串 s = s1 s2 s3 · · · sn,变换后的 01 串 s ′ = s ′ 1 s ′ 2 s ′ 3 · · · s ′ n 为: s ′ 1 = s1; s ′ i = si−1 ⊕ si。 其中 a ⊕ b 表示两个二进制的异或,当 a 和 b 相同时结果为 0,当 a 和 b 不同时结果为 1。 请问,经过 t 次变换后的 01 串是什么?

【输入格式】 输入的第一行包含两个整数 n, t,分别表示 01 串的长度和变换的次数。 第二行包含一个长度为 n 的 01 串。

【输出格式】 输出一行包含一个 01 串,为变换后的串。

样例输入】 5 3 10110

【样例输出】 11010 试题 G: 异或变换 9 第十二届蓝桥杯大赛软件赛决赛 C/C++ 大学 B 组

【样例说明】 初始时为 10110,变换 1 次后变为 11101,变换 2 次后变为 10011,变换 3 次后变为 11010。

【评测用例规模与约定】

对于 40% 的评测用例,1 ≤ n ≤ 100, 1 ≤ t ≤ 1000。

对于 80% 的评测用例,1 ≤ n ≤ 1000, 1 ≤ t ≤ 109。

对于所有评测用例,1 ≤ n ≤ 10000, 1 ≤ t ≤ 1018。

试题I: 试翻转括号序列(时间限制: 2.0s 内存限制: 512.0MB 本题总分:25 分)

【问题描述】

给定一个长度为 n 的括号序列,要求支持两种操作: 1. 将 [Li , Ri ] 区间内(序列中的第 Li 个字符到第 Ri 个字符)的括号全部翻 转(左括号变成右括号,右括号变成左括号)。 2. 求出以 Li 为左端点时,最长的合法括号序列对应的 Ri (即找出最大的 Ri 使 [Li , Ri ] 是一个合法括号序列)。

【输入格式】

输入的第一行包含两个整数 n, m,分别表示括号序列长度和操作次数。 第二行包含给定的括号序列,括号序列中只包含左括号和右括号。 接下来 m 行,每行描述一个操作。如果该行为 “1 Li Ri”,表示第一种操作, 区间为 [Li , Ri ] ;如果该行为 “2 Li” 表示第二种操作,左端点为 Li。

【输出格式】

对于每个第二种操作,输出一行,表示对应的 Ri。如果不存在这样的 Ri, 请输出 0。

【样例输入】

7 5

( ( ( ) ) ( )

2 3

2 2

1 3 5

2 3

2 1 

【样例输出】

4

7

0

0

【评测用例规模与约定】

对于 20% 的评测用例,n, m ≤ 5000;

对于 40% 的评测用例,n, m ≤ 30000;

对于 60% 的评测用例,n, m ≤ 100000;

对于所有评测用例,1 ≤ n ≤ 106 , 1 ≤ m ≤ 2 × 105。

试题J: 异或三角(时间限制: 1.0s 内存限制: 256.0MB 本题总分:25 分)

【问题描述】

给定 T 个数 n1, n2, · · · , nT,对每个 ni 请求出有多少组 a, b, c 满足: 1. 1 ≤ a, b, c ≤ ni; 2. a ⊕ b ⊕ c = 0,其中 ⊕ 表示二进制按位异或; 3. 长度为 a, b, c 的三条边能组成一个三角形。

【输入格式】

输入的第一行包含一个整数 T。 接下来 T 行每行一个整数,分别表示 n1, n2, · · · , nT。

【输出格式】

输出 T 行,每行包含一个整数,表示对应的答案。

【样例输入】

2 6 114514

【样例输出】

6 11223848130

【评测用例规模与约定】

对于 10% 的评测用例,T = 1, 1 ≤ ni ≤ 200;

对于 20% 的评测用例,T = 1, 1 ≤ ni ≤ 2000;

对于 50% 的评测用例,T = 1, 1 ≤ ni ≤ 2 20;

对于 60% 的评测用例,1 ≤ T ≤ 100000, 1 ≤ ni ≤ 2 20;

对于所有评测用例,1 ≤ T ≤ 100000, 1 ≤ ni ≤ 2 30。

#include <iostream>
#include <unordered_map>

using namespace std;

unordered_map<int,int> visited;
unordered_map<int,int> dpmap;

int dp(int n)
{
    if(n==1){return 0;}
    if(visited[n]==1){return dpmap[n];}

    int result = dp(n-1);
    for(int i=n/2;i<n;i++)
    {
        for(int j=i-1;j>0;j--)
        {
            if(i+j<=n){continue;}
            if((i^j^n) == 0){result++;}
        }
    }
    visited[n] = 1;
    dpmap[n] = result;
    return result;
}

int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        cout<<dp(n);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_52088967/article/details/123974143