[题解][蓝桥杯]2021第十二届蓝桥杯国赛C/C++B组(未完待续)

48 篇文章 4 订阅
12 篇文章 0 订阅

前言

2021年6月,我参加了蓝桥杯国赛。

这是我第一次参加蓝桥杯国赛。

我将我的题解和分析记录于此。

希望这份来自于我个人的经验题解对于我、对于看这篇文章的你都有收获。

这篇文章中的题解为本人原创,题解和代码是我在写这篇文章时重新编写的,并非比赛时提交的代码(赛后无法获取到自己提交的答案)。

下文中提供的正确答案为本人在网上收集到的答案,所以不排除正确答案不正确的可能。

本人大一,能力有限,如有疏漏欢迎评论区指正,非常感谢。

由于本人时间有限,这篇文章无法一气呵成,见谅。


试题A:宽带(填空题)

总分:5分

题目描述

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

我的答案

200

正确答案

25

分析

度娘易得,

Mbps=Mbit/s 即 兆比特每秒,也就是 1,000,000bit/s

所以200Mbps的宽带,理论上每秒最多可以从网上下载 200 ÷ 8 = 25 200 \div 8 = 25 200÷8=25MB的内容。

这道题失分挺可惜的。

因为就在比赛的前几天,我在生活中遇到了一个类似的问题,却想当然的得出了自己错误的答案而不自知。


试题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

正确答案

1903

分析

这一题的思路非常简单,只要从1到20210605,逐个判断是否为纯质数即可。

代码如下:

#include<cstdio>
using namespace std;
bool isPrime(int a){	// 判断是否为质数
	if(a == 2){
		return true;
	}
	if(a < 2 || a % 2 == 0){
		return false;
	}
	for(int i = 3;i * i <= a;i += 2){
		if(a % i == 0){
			return false;
		}
	}
	return true;
}
bool isRealPrime(int a){	// 判断是否为纯质数
	if(!isPrime(a)){
		return false;
	}
	do{
		if(!isPrime(a % 10)){
			return false;
		}
		a /= 10;
	}while(a != 0);
	return true;
}
int main(){
	int count = 0;
	for(int i = 1;i <= 20210605;i++){
		if(isRealPrime(i)){
			count++;
		}
	}
	printf("%d\n",count);
}

我的代码思路比较简单,没有从算法上对程序的速度进行优化。在我的计算机上计算约12秒可出答案。

main函数中是从1到20210605进行迭代判断。

isRealPrime函数中调用了isPrime函数对参数是否为纯函数进行了判断。

试题C:完全日期(填空题)

总分:10分

问题描述

​ 如果一个日期中年月日各位数字之和是完全平方数,则称为一个完全日期。

​ 例如:2021年6月5日的各位数字之和为2 + 0 + 2 + 1 + 6 + 5 = 16,而16是一个完全平方数,它是4的平方。所以2021年6月5日是一个完全日期。

​ 例如:2001年6月23日的各位数字之和为2 + 0 + 2 + 1 + 6 + 2 + 3 = 16,是一个完全平方数。所以2021年6月23日也是一个完全日期。

​ 请问,从2001年1月1日到2021年12月31日中,一共有多少个完全日期?

我的答案

977

正确答案

977

思路和分析

​ 这一题的对于完全日期 进行了定义之后,便直接发问,在指定时间段内共有多少个完全日期。

​ 思路简单而粗暴——对这个日期内的每一天逐个判断,做统计。

上代码:

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int M[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};// 将每一个月的号数上限提前记录在表中
int calc(const int &a){    // 返回a各位数之和
	int t = a >= 0 ? a : -a;    // 防止负数出现错误的返回结果,提高鲁棒性
	int sum = 0;
	do{
		sum += t % 10;
		t /= 10;
	}while(t != 0);
	return sum;
}
bool check(const int &year,const int &month,const int &day){ // 检查传入的日期是否为完全日期
	int sum = calc(year) + calc(month) + calc(day);
	int t = sqrt(sum);
	if(t * t == sum){
		return true;
	}
	return false;
}
int main(){
	int count = 0;	// 统计完全日期数
    for(int y = 2001;y <= 2021;y++){
    	for(int m = 1;m <= 12;m++){
    		for(int d = 1;d <= M[m];d++){   // 遍历日期
				if(check(y,m,d)){
					count ++;
				}
			}
		}
		if((y % 4 == 0 && y % 100 != 0) || (y % 400 == 0)){    // 如果这一年是闰年,多判断2月29日这一天
			if(check(y,2,29)){
				count ++;
			}
		}
	}
	printf("%d\n",count);
	return 0;
}

注意:为了提高解题的效率,33行对于闰年中29日的判断方法在移植上会存在局限——当遍历到闰年时,必定会同时遍历到这一年的2月29日。但对于这道题,不会产生问题,所以不再进行优化。

试题D:最小权值(填空题)

总分:10分


本篇文章为本人原创。转发请注明出处。

欢迎评论留言与我交流。

如果文章内容有疏漏,欢迎您在评论区指出。

感谢阅读,您的点赞和关注,是对我最大的鼓励和支持!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wingaso

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值