前言
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分
本篇文章为本人原创。转发请注明出处。
欢迎评论留言与我交流。
如果文章内容有疏漏,欢迎您在评论区指出。
感谢阅读,您的点赞和关注,是对我最大的鼓励和支持!