0
点赞
收藏
分享

微信扫一扫

第十二届蓝桥杯B组国赛真题详解及考点总结

试题A:

在这里插入图片描述

考点:计算机网络

答案:25

题解:

200M的带宽理论下载速率为1024×200÷8=25600KB/s=25M/s
1Mbps代表每秒传输1, 000, 000位(bit),即每秒传输的数据量为:1, 000, 000/8 Byte,即125, 000Byte/s = 125KB/s
200Mbps = 200 * 125KB/s = 25, 000 KB/s = 25 MB/s

试题B:

在这里插入图片描述

考点:数位截取、质数筛

答案:1903

题解:

一位的质数为2,3,5,7,对于一个数字的每一位判断是否为上面4个数字之一,且它本身是不是质数,可以先预处理出1-20210605中所有质数,这一块需要用质数筛做这,当然也可以直接暴力找就是时间需要比较长(可能比赛结束也跑不出来),然后在累计是质数且每一位都是质数的数即可,总数据量很小,直接暴力循环判断即可。

#include<bits/stdc++.h>
using namespace std;
const int N = 20210605;
int st[N];
bool check(int x)
{
	while (x)
	{   
		int t = x % 10;
		if (t==2||t==3||t==5||t==7)x /= 10;
		else return 0;
	}
	return 1;
}
int main()
{    
	for (int i = 2; i <= N; i++)//埃氏筛大约需要5s时间可以跑出结果
	{
		if (st[i] == 0)
			for (int j = 2; j * i <= N; j++)
				st[i * j] = 1;
	}
	int res = 0;
	for (int i = 2; i <= N; i++)
	{
		if (!st[i] && check(i))res++;
	}
	cout << res << endl;
}

试题C:

在这里插入图片描述

考点:模拟、日期

答案:977

题解:

日期也是蓝桥杯最最最频繁的考点了,只要注意一下闰年,然后暴力循环即可,判断完全平方数我们可以看出一共8位数那所有数的和不超过72,至多为8的平方,把1-8的平方预处理出来然后枚举每一天即可,。
解法1
Excel处理数据,由于可能自己模拟时间的时候会出错,所以可以从Excel得到所有日期,储存到记事本中,然后借助c++程序进行判断是否为完全平方数即可。
在这里插入图片描述

#include<cstdio>
#include<iostream>
#include<string>
using namespace std;

int res = 0;

void solve(int x) {
	for(int i = 0; i < 100; i++) {
		if(i * i == x) res++;
	}
}

int main() {
	string line;
	while(getline(cin, line)) {
		int len = line.length();
		int sum = 0;
		for(int i = 0; i < len; i++) {
			if(isdigit(line[i])) sum += line[i] - '0';
		}
		solve(sum);
		cout << res << endl;
	}
}

解法2
思路一致不过是直接在程序中模拟日期。

/**977**/
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 * 2 + 5;
int f[maxn];
int m[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31};
bool Run(int year) {
    if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
        return true;
    }
    return false;
}
bool check(int y, int m, int d) {
    int sum = 0;
    while (y > 0) {
        sum += y % 10;
        y /= 10;
    }
    while (m > 0) {
        sum += m % 10;
        m /= 10;
    }
    while (d > 0) {
        sum += d % 10;
        d /= 10;
    }
    if (f[sum] == 1) {
        return true;
    }
    return false;
}
void init() {
    f[1] = 1;
    for (int i = 2; i * i < 100; i++) {
        f[i * i] = 1;
    }
}
int main() {
    //从2001.1.1到2021.12.31 // 平年2月 28天 闰年29天
    init();
    int ans = 0;
    for (int i = 2001; i <= 2021; i++) {//year
       
        if (Run(i)) {//如果是闰年
            m[2] = 29;
        }
        else m[2] = 28;
        for (int j = 1; j <= 12; j++) {//month
            for (int k = 1; k <= m[j]; k++) {
                if (check(i, j, k)) {
               
                    ans++;
                }
            }
        }
    }
    cout << ans << endl;
    return 0;
}

试题D:

在这里插入图片描述

考点:动态规划、递归转递推

答案:2653631372

题解:

很明显递归直接求解会超时,那我们就转换思路,递归转递推,我们需要求得是有2021个节点的二叉树值最小,那我们dp[i]就设为有i个节点的二叉树最小值,然后我们状态改如何转移呢,当多一个节点作为父节点时,我们只需要考虑左右子树节点个数的搭配从中取个最小值即可,所以枚举左子树节点个数,右子树节点个数为i-j-1,然后根据上面的权值方程进行赋值即可。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll dp[2022];//dp[i]表示有i个节点的二叉树的最小值
int main()
{
    memset(dp,0x7f,sizeof(dp));//初始化最大值;
    dp[0]=0;//根据题意,当子树为空时权值为0;
    for(int i=1;i<=2021;i++)//自下而上;
        for(int j=0;j<i;j++)//枚举左子树节点的个数为j 则右子树为i-1-j
        	dp[i]=min(dp[i],1+2*dp[j]+3*dp[i-1-j]+j*j*(i-1-j));
    cout<<dp[2021]<<endl;
    return 0;
}

试题E:

在这里插入图片描述

试题F:

在这里插入图片描述
在这里插入图片描述

试题G:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

试题H:

在这里插入图片描述
在这里插入图片描述

试题I:

在这里插入图片描述
在这里插入图片描述

试题J:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

举报

相关推荐

0 条评论