第十一届蓝桥杯第三场软件类省赛 C++ B组 题解(一)

简介: 第十一届蓝桥杯第三场软件类省赛 C++ B组 题解

试题 A: 数青蛙

“一只青蛙一张嘴,两只眼睛四条腿。两只青蛙两张嘴,四只眼睛八条腿。三只青蛙三张嘴,六只眼睛十二条腿。……二十只青蛙二十张嘴,四十只眼睛八十条腿。”

请问上面这段文字,如果完全不省略,全部写出来,从 1 到 20 只青蛙,总共有多少个汉字。

约定:数字 2 单独出现读成 “两”,在其他数里面读成 “二”,例如 “十二”。10 读作 “十”,11 读作 “十一”,22 读作 “二十二”。请只计算汉字的个数,标点符号不计算。

答案353

上限20只青蛙,腿最多80只,所以只需要考虑1~80的汉字个数即可.

个位数一位;11~19以及10的倍数两位;其余情况三位

1. #include<iostream>
2. #include<string>
3. #include<cstring>
4. #include<algorithm>
5. #include<cmath>
6. #include<cstdio>
7. using namespace std;
8. int n(int x){
9.  if(x<=10) return 1;
10.   if(x%10==0) return 2;
11.   if(x<20) return 2;
12.   return 3;
13. }
14. int main(){
15.   int sum = 0;
16.   for(int i = 1 ; i <=20 ; i ++){
17.     int a = i;
18.     int b = i + i;
19.     int c = i *4;
20.     sum += 10;
21.     sum += n(a)*2;
22.     sum+=n(b) + n(c);
23.   }
24.   cout<<sum<<endl;
25.   return 0;
26. }

 

试题 B: 互质

今年是 2020 年,今天是 10 月 18 日。

请问在 1 到 2020 中,有多少个数与 1018 互质。

答案:1008

因为是填空题,所以不需要考虑什么算法,直接暴力试就可

1. #include<iostream>
2. #include<string>
3. #include<cstring>
4. #include<algorithm>
5. #include<cmath>
6. #include<cstdio>
7. using namespace std;
8. 
9. int gcd2(int a,int b){
10.   return b==0?a:gcd(b,a%b);
11. }
12. int main(){
13.   int sum = 0;
14.   for(int i = 1 ; i <= 2020; i ++){
15.     if(gcd2(1018,i) == 1){
16.       sum ++;
17.     }
18.   }
19.   cout<< sum <<endl;
20.   return 0;
21. }

 

 

试题 C: 车牌

 

A 市的车牌由六位组成,其中前三位可能为数字 0 至 9,或者字母 A 至 F,每位有 16 种可能。后三位只能是数字 0 至 9。为了减少攀比,车牌中不能有连续三位是相同的字符。

例如,202020 是合法的车牌,AAA202 不是合法的车牌,因为前三个字母相同。

请问,A 市有多少个合法的车牌?

答案:3997440


总共情况为16*16*16*10*10*10

第一位第二位第三位字符一致,可以看做一位,有16种情况,第四位第五位第六位分别有10种情况

第一位16种情况,第二位第三位第四位一致,看做一位,有10种情况,第五位第六位分别有10种情况

第一位16种情况,第二位16种情况,第三第四第五位一致看做一位,有10种情况,第六位10种情况

第一位第二位第三位分别16种情况,第四位第五位第六位一致,看做一位,有10种情况

采用正难则反的思想,总数减去排除情况数,就是答案

1. #include<iostream>
2. #include<string>
3. #include<cstring>
4. #include<algorithm>
5. #include<cmath>
6. #include<cstdio>
7. using namespace std;
8. 
9. int main(){
10.   int sum = 16*16*16*10*10*10;
11.   sum -= 16*10*10*10;
12.   sum -= 16*10*10*10;
13.   sum -= 16*16*10*10;
14.   sum -= 16*16*16*10;
15.   cout<<sum<<endl;
16.   return 0;
17. }

 

 

试题 D: Fibonacci 集合

 

小蓝定义了一个 Fibonacci 集合 F,集合的元素如下定义:

1. 最小的 5 个 Fibonacci 数 1, 2, 3, 5, 8 属于集合 F。

2. 如果一个元素 x 属于 F,则 3x + 2、5x + 3 和 8x + 5 都属于集合 F。

3. 其他元素都不属于 F。

请问,这个集合中的第 2020 小元素的值是多少?

 

答案 41269

 

标准深搜题,数字要求也不大,暴力即可

从最小的五个数开始搜索,把搜索到的数字置一,然后再找地2020个置一的数字即可

1. #include<iostream>
2. #include<string>
3. #include<cstring>
4. #include<algorithm>
5. #include<cmath>
6. #include<cstdio>
7. using namespace std;
8. int fx[100010];
9. bool is[100010];
10. void dfs(int n){
11.   if(n > 100000) return ;
12.   is[n] = true;
13.   dfs(n*3+2);
14.   dfs(n*5+3);
15.   dfs(n*8+5);
16. }
17. int main(){
18.   dfs(1);
19.   dfs(2);
20.   dfs(3);
21.   dfs(5);
22.   dfs(8);
23.   int sum = 0;
24.   for(int i = 1;i<=100010;i++){
25.     if(is[i]){
26.       sum ++;
27.       cout<< sum << " ge  = " << i<<endl;
28.       if(sum == 2020){
29.         break;
30.       }
31.     }
32.   }
33.   return 0;
34. }

 

试题 E: 上升子串

小蓝有一个字母矩阵,他喜欢和小伙伴们在这个矩阵上玩一些游戏。今天,他打算玩找上升子串的游戏。游戏是合作性质的。小蓝和小伙伴们首先要在矩阵中指定一个位置,然后从这个位置开始,向上下左右相邻位置移动,移动必须满足所到达位置上的字母比当前位置大。小蓝和小伙伴们可以移动任意多次,也可以随时停下来,这样就找到了一个上升子串。只要子串在矩阵中的位置不同,就认为是不同的子串。

小蓝想知道,一共可以找到多少个上升子串。小蓝的矩阵很大,已经放在了试题目录下面,叫 inc.txt。为了更清楚的

描述问题,他还找了一个很小的矩阵用来解释。

例如,对于矩阵:

1. AB
2. BC

 

可以找到 4 个长度为 1 的上升子串、4 个长度为 2 的上升子串、2 个长度

为 3 的上升子串,共 10 个。

现在,请你对于小蓝的大矩阵,找到上升子串的数量。

答案未知

这题暴力过不去,比赛的时候跑了两个多小时,还在跑......

1. #include<iostream>
2. #include<string>
3. #include<cstring>
4. #include<algorithm>
5. #include<cmath>
6. #include<cstdio>
7. #include<queue>
8. using namespace std;
9. char a[102][102];
10. int sum;
11. struct mu{
12.   int x;
13.   int y;
14.   char maxChar;
15.   mu(int xx,int yy,char z){
16.     x = xx;
17.     y = yy;
18.     maxChar = z;
19.   }
20. };
21. bool check(int x){
22.   if(x<0 || x >= 100) return false;
23.   return true;
24. }
25. void bfs(int x,int y){
26.   queue<mu> q;
27.   q.push(mu(x,y,a[x][y]));
28.   while(!q.empty()){
29.     mu mm = q.front();
30.     sum ++;
31.     cout<<sum<<endl;
32.     q.pop();
33.     if(check(mm.x - 1) && mm.maxChar < a[mm.x - 1][mm.y]){
34.       mu m2 = mu(mm.x - 1,mm.y,a[mm.x - 1][mm.y]);
35.       q.push(m2);
36.     }
37.     if(check(mm.x + 1) && mm.maxChar < a[mm.x + 1][mm.y]){
38.       mu m3 = mu(mm.x + 1,mm.y,a[mm.x + 1][mm.y]);
39.       q.push(m3);
40.     }
41.     if(check(mm.y + 1) && mm.maxChar < a[mm.x][mm.y + 1]){
42.       mu m4 = mu(mm.x,mm.y + 1,a[mm.x][mm.y + 1]);
43.       q.push(m4);
44.     }
45.     if(check(mm.y - 1) && mm.maxChar < a[mm.x][mm.y - 1]){
46.       mu m5 = mu(mm.x,mm.y - 1,a[mm.x][mm.y - 1]);
47.       q.push(m5);
48.     }
49.   }
50. }
51. int main(){
52.   sum = 0;
53.   for(int i = 0 ; i < 100;i++){
54.     cin>>a[i];
55.   }
56.   for(int i = 0 ; i < 100;i++){
57.     for(int j = 0 ; j < 100 ; j ++){
58.       bfs(i,j);
59.     }
60.   }
61.   cout<<sum<<endl;
62.   return 0;
63. }

 

试题 F: 日期识别

 

小蓝要处理非常多的数据,其中有一些数据是日期。在小蓝处理的日期中有两种常用的形式:英文形式和数字形式。英文形式采用每个月的英文的前三个字母作为月份标识,后面跟两位数字表示日期,月份标识第一个字母大写,后两个字母小写,日期小于 10 时要补前导 0。1 月到 12 月英文的前三个字母分别是 Jan、Feb、Mar、Apr、May、Jun、Jul、Aug、Sep、Oct、Nov、Dec。数字形式直接用两个整数表达,中间用一个空格分隔,两个整数都不写前导 0。其中月份用 1 至 12 分别表示 1 月到 12 月。

输入一个日期的英文形式,请输出它的数字形式。

 

1. 【样例输入】
2. Feb08
3. 【样例输出】
4. 2 8
5. 【样例输入】
6. Oct18
7. 【样例输出】
8. 10 18

话不多说,暴力

1. #include<iostream>
2. #include<string>
3. #include<cstring>
4. #include<algorithm>
5. #include<cmath>
6. #include<cstdio>
7. using namespace std;
8. void run(string s){
9.  if(s[0] == 'J' && s[1] == 'a' && s[2] == 'n'){
10.     printf("1 ");
11.   }
12.   else if(s[0] == 'F' && s[1] == 'e' && s[2] == 'b'){
13.     printf("2 ");
14.   }
15.   else if(s[0] == 'M' && s[1] == 'a' && s[2] == 'r'){
16.     printf("3 ");
17.   }
18.   else if(s[0] == 'A' && s[1] == 'p' && s[2] == 'r'){
19.     printf("4 ");
20.   }
21.   else if(s[0] == 'M' && s[1] == 'a' && s[2] == 'y'){
22.     printf("5 ");
23.   }
24.   else if(s[0] == 'J' && s[1] == 'u' && s[2] == 'n'){
25.     printf("6 ");
26.   }
27.   else if(s[0] == 'J' && s[1] == 'u' && s[2] == 'l'){
28.     printf("7 ");
29.   }
30.   else if(s[0] == 'A' && s[1] == 'u' && s[2] == 'g'){
31.     printf("8 ");
32.   }
33.   else if(s[0] == 'S' && s[1] == 'e' && s[2] == 'p'){
34.     printf("9 ");
35.   }
36.   else if(s[0] == 'O' && s[1] == 'c' && s[2] == 't'){
37.     printf("10 ");
38.   }
39.   else if(s[0] == 'N' && s[1] == 'o' && s[2] == 'v'){
40.     printf("11 ");
41.   }
42.   else if(s[0] == 'D' && s[1] == 'e' && s[2] == 'c'){
43.     printf("12 ");
44.   }
45.   if(s[3] != '0'){
46.     cout<<s[3];
47.   }
48.   cout<<s[4]<<endl;
49. }
50. int main(){
51.   string str;
52.   while(cin>>str){
53.     run(str);
54.   }
55.   return 0;
56. }

 

试题 G: 乘法表

 

九九乘法表是学习乘法时必须要掌握的。在不同进制数下,需要不同的乘

法表。

例如,四进制下的乘法表如下所示:

1. 1*1=1
2. 2*1=2 2*2=10
3. 3*1=3 3*2=12 3*3=21

请注意,乘法表中两个数相乘的顺序必须为样例中所示的顺序,不能随意

交换两个乘数。

给定 P,请输出 P 进制下的乘法表。

1. 【输入格式】
2. 输入一个整数 P。
3. 【输出格式】
4. 输出 P 进制下的乘法表。P 进制中大于等于 10 的数字用大写字母 A、B、 C、· · · 表示。
5. 【样例输入】
6. 4
7. 【样例输出】
8. 1*1=1
9. 2*1=2 2*2=10
10. 3*1=3 3*2=12 3*3=21
11. 
12. 【样例输入】
13. 8
14. 【样例输出】
15. 1*1=1
16. 2*1=2 2*2=4
17. 3*1=3 3*2=6 3*3=11
18. 4*1=4 4*2=10 4*3=14 4*4=20
19. 5*1=5 5*2=12 5*3=17 5*4=24 5*5=31
20. 6*1=6 6*2=14 6*3=22 6*4=30 6*5=36 6*6=44
21. 7*1=7 7*2=16 7*3=25 7*4=34 7*5=43 7*6=52 7*7=61

【评测用例规模与约定】

对于所有评测数据,2 ≤ P ≤ 36。

 

使用栈进行进制转换即可,注意10以上进制的需要输出字符A-F

1. #include<iostream>
2. #include<string>
3. #include<cstring>
4. #include<algorithm>
5. #include<cmath>
6. #include<cstdio>
7. #include<stack>
8. using namespace std;
9. void printNum(int num,int p){
10.   stack<int> s;
11.   while(num>0){
12.     s.push(num%p);
13.     num/=p;
14.   }
15.   while(!s.empty()){
16.     if(s.top() > 9){
17.       printf("%c",'A'+ s.top() - 10);
18.     }
19.     else{
20.       cout<<s.top();
21.     }
22.     s.pop();
23.   }
24. }
25. void run(int p){
26.   for(int i = 1 ; i < p ; i ++){
27.     for(int j = 1;j <= i;j ++){
28.       int sum = i * j;
29.       if(j!=1){
30.         printf(" ");
31.       }
32.       if(i > 9){
33.         printf("%c",'A'+i-10);
34.       }else{
35.         printf("%d", i);
36.       }
37.       printf("*");
38.       if(j > 9){
39.         printf("%c",'A'+j-10);
40.       }else{
41.         printf("%d", j);
42.       }
43.       printf("=");
44.       printNum(sum,p);
45.     }
46.     printf("\n");
47.   }
48. }
49. int main(){
50.   int p;
51.   while(cin>>p){
52.     run(p);
53.   }
54.   return 0;
55. }

 

目录
打赏
0
0
0
0
397
分享
相关文章
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
【C++进阶】特殊类设计 && 单例模式
通过对特殊类设计和单例模式的深入探讨,我们可以更好地设计和实现复杂的C++程序。特殊类设计提高了代码的安全性和可维护性,而单例模式则确保类的唯一实例性和全局访问性。理解并掌握这些高级设计技巧,对于提升C++编程水平至关重要。
40 16
类和对象(中 )C++
本文详细讲解了C++中的默认成员函数,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载和取地址运算符重载等内容。重点分析了各函数的特点、使用场景及相互关系,如构造函数的主要任务是初始化对象,而非创建空间;析构函数用于清理资源;拷贝构造与赋值运算符的区别在于前者用于创建新对象,后者用于已存在的对象赋值。同时,文章还探讨了运算符重载的规则及其应用场景,并通过实例加深理解。最后强调,若类中存在资源管理,需显式定义拷贝构造和赋值运算符以避免浅拷贝问题。
类和对象(上)(C++)
本篇内容主要讲解了C++中类的相关知识,包括类的定义、实例化及this指针的作用。详细说明了类的定义格式、成员函数默认为inline、访问限定符(public、protected、private)的使用规则,以及class与struct的区别。同时分析了类实例化的概念,对象大小的计算规则和内存对齐原则。最后介绍了this指针的工作机制,解释了成员函数如何通过隐含的this指针区分不同对象的数据。这些知识点帮助我们更好地理解C++中类的封装性和对象的实现原理。
|
21天前
|
【c++】继承(继承的定义格式、赋值兼容转换、多继承、派生类默认成员函数规则、继承与友元、继承与静态成员)
本文深入探讨了C++中的继承机制,作为面向对象编程(OOP)的核心特性之一。继承通过允许派生类扩展基类的属性和方法,极大促进了代码复用,增强了代码的可维护性和可扩展性。文章详细介绍了继承的基本概念、定义格式、继承方式(public、protected、private)、赋值兼容转换、作用域问题、默认成员函数规则、继承与友元、静态成员、多继承及菱形继承问题,并对比了继承与组合的优缺点。最后总结指出,虽然继承提高了代码灵活性和复用率,但也带来了耦合度高的问题,建议在“has-a”和“is-a”关系同时存在时优先使用组合。
67 6
类和对象(下)C++
本内容主要讲解C++中的初始化列表、类型转换、静态成员、友元、内部类、匿名对象及对象拷贝时的编译器优化。初始化列表用于成员变量定义初始化,尤其对引用、const及无默认构造函数的类类型变量至关重要。类型转换中,`explicit`可禁用隐式转换。静态成员属类而非对象,受访问限定符约束。内部类是独立类,可增强封装性。匿名对象生命周期短,常用于临时场景。编译器会优化对象拷贝以提高效率。最后,鼓励大家通过重复练习提升技能!
探秘:基于 C++ 的局域网电脑控制软件自适应指令分发算法
在现代企业信息化架构中,局域网电脑控制软件如同“指挥官”,通过自适应指令分发算法动态调整指令发送节奏与数据量,确保不同性能的终端设备高效运行。基于C++语言,利用套接字实现稳定连接和线程同步管理,结合实时状态反馈,优化指令分发策略,提升整体管控效率,保障网络稳定,助力数字化办公。
76 19
【C++篇】深度解析类与对象(中)
在上一篇博客中,我们学习了C++类与对象的基础内容。这一次,我们将深入探讨C++类的关键特性,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载、以及取地址运算符的重载。这些内容是理解面向对象编程的关键,也帮助我们更好地掌握C++内存管理的细节和编码的高级技巧。
【C++篇】深度解析类与对象(上)
在C++中,类和对象是面向对象编程的基础组成部分。通过类,程序员可以对现实世界的实体进行模拟和抽象。类的基本概念包括成员变量、成员函数、访问控制等。本篇博客将介绍C++类与对象的基础知识,为后续学习打下良好的基础。
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等