第九届蓝桥杯C/C++ 大学B组省赛题目及答案解析
2021/4/12 22:28:46
本文主要是介绍第九届蓝桥杯C/C++ 大学B组省赛题目及答案解析,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
目录
- 试题A:第几天
- 试题B:明码
- 试题C:乘积尾零
- 试题D:测试次数
- 试题E:快速排序
- 试题F:递增三元组
- 试题G:螺旋折线
- 试题H:日志统计
- 试题I:全球变暖
- 试题J:乘积最大
试题A:第几天
【问题描述】
【答案】:125
【代码解析】
经典的日期题,难度较小,可直接口算。
31+29+31+30+4=125
试题B:明码
【问题描述】
4 0 4 0 4 0 4 32 -1 -16 4 32 4 32 4 32 4 32 4 32 8 32 8 32 16 34 16 34 32 30 -64 0 16 64 16 64 34 68 127 126 66 -124 67 4 66 4 66 -124 126 100 66 36 66 4 66 4 66 4 126 4 66 40 0 16 4 0 4 0 4 0 4 32 -1 -16 4 32 4 32 4 32 4 32 4 32 8 32 8 32 16 34 16 34 32 30 -64 0 0 -128 64 -128 48 -128 17 8 1 -4 2 8 8 80 16 64 32 64 -32 64 32 -96 32 -96 33 16 34 8 36 14 40 4 4 0 3 0 1 0 0 4 -1 -2 4 0 4 16 7 -8 4 16 4 16 4 16 8 16 8 16 16 16 32 -96 64 64 16 64 20 72 62 -4 73 32 5 16 1 0 63 -8 1 0 -1 -2 0 64 0 80 63 -8 8 64 4 64 1 64 0 -128 0 16 63 -8 1 0 1 0 1 0 1 4 -1 -2 1 0 1 0 1 0 1 0 1 0 1 0 1 0 5 0 2 0 2 0 2 0 7 -16 8 32 24 64 37 -128 2 -128 12 -128 113 -4 2 8 12 16 18 32 33 -64 1 0 14 0 112 0 1 0 1 0 1 0 9 32 9 16 17 12 17 4 33 16 65 16 1 32 1 64 0 -128 1 0 2 0 12 0 112 0 0 0 0 0 7 -16 24 24 48 12 56 12 0 56 0 -32 0 -64 0 -128 0 0 0 0 1 -128 3 -64 1 -128 0 0
【答案】:387420489
【代码解析】
感觉这个题在考基本功,想做出这个题就必须知道负数的二进制表示方法,是以补码的形式表示。下面是我写的比较繁冗的常规写法,除此之外还可利用bitset头文件去快速得到答案。在看出字符后,简单写一个pow函数即可。
#include<iostream> #include<cmath> using namespace std; inline void circulate(int n) { int str[8]={0}; int k=abs(n); int i=7; while(k) { int m=k%2; str[i--]=m; k/=2; } if(n>=0) { for(int j=0;j<8;j++) { if(str[j]==1) { str[j]='*'; printf("%c",str[j]); } else{ str[j]=' '; printf("%c",str[j]); } } } if(n<0) { for(int j=0;j<8;j++) { if(str[j]==0) { str[j]=1; continue; } if(str[j]==1) { str[j]=0; continue; } } int sum; for(int j=0;j<8;j++) { sum+=str[j]*pow(2,7-j); } sum+=1; int str[8]={0}; int k=abs(sum); int i=7; while(k) { int m=k%2; str[i--]=m; k/=2; } for(int j=0;j<8;j++) { if(str[j]==1) { str[j]='*'; printf("%c",str[j]); } else{ str[j]=' '; printf("%c",str[j]); } } } } int main() { int p; for(int u=0;u<10;u++) for(int i=0;i<16;i++) { for(int j=0;j<2;j++) { cin >> p; circulate(p); } cout << endl; } return 0; }
点击:bitset头文件方法
试题C:乘积尾零
【问题描述】
5650 4542 3554 473 946 4114 3871 9073 90 4329 2758 7949 6113 5659 5245 7432 3051 4434 6704 3594 9937 1173 6866 3397 4759 7557 3070 2287 1453 9899 1486 5722 3135 1170 4014 5510 5120 729 2880 9019 2049 698 4582 4346 4427 646 9742 7340 1230 7683 5693 7015 6887 7381 4172 4341 2909 2027 7355 5649 6701 6645 1671 5978 2704 9926 295 3125 3878 6785 2066 4247 4800 1578 6652 4616 1113 6205 3264 2915 3966 5291 2904 1285 2193 1428 2265 8730 9436 7074 689 5510 8243 6114 337 4096 8199 7313 3685 211
【答案】:31
【代码解析】
看到这个题的第一眼就是直接乘起来,但由于数据量太大又不可能不做任何处理,所以保留后6,7位数字去判断末尾是否有0,有的话计数并将其去掉即可得到答案。后来看到别的博主,提到所有的0都一定是2*5产生的,所以将每个数拆成一堆2乘上一堆5再乘上一个数,之后统计下有多少个2和多少个5取少的那个就是答案。
点击:拆分法
#include <bits/stdc++.h> using namespace std; int main() { long long n,sum=1; int num=0; for(int i=0;i<100;i++) { cin >> n; sum*=n; sum%=100000; int k=sum; while(k) { int m=k%10; if(m==0) { num++; k/=10; } else{ break; } } sum=k; } cout << num << endl; return 0; }
试题D:测试次数
【问题描述】
【答案】:19
【代码解析】
一看到“最多测试多少次”,个人就感觉是DP,但始终不得其法。有一篇博文供大家参考,上面讲解的很清楚:
https://blog.csdn.net/weixin_43846139/article/details/88699311
试题E:快速排序
【问题描述】
#include <stdio.h> int quick_select(int a[], int l, int r, int k) { int p = rand() % (r - l + 1) + l; int x = a[p]; { int t = a[p]; a[p] = a[r]; a[r] = t; } int i = l, j = r; while(i < j) { while(i < j && a[i] < x) i++; if(i < j) { a[j] = a[i]; j--; } while(i < j && a[j] > x) j--; if(i < j) { a[i] = a[j]; i++; } } a[i] = x; p = i; if(i - l + 1 == k) return a[i]; if(i - l + 1 < k) return quick_select(); //填空 else return quick_select(a, l, i - 1, k); } int main() { int a[] = {1, 4, 2, 8, 5, 7, 23, 58, 16, 27, 55, 13, 26, 24, 12}; printf("%d\n", quick_select(a, 0, 14, 4)); return 0; }
【答案】:答案: a, i+1, r, k-(i-l+1)
【代码解析】
这里想要运行成功需要手动添加一个头文件stdlib.h。自己拿张纸手动模拟一下程序运行过程,应该很快就能出来。
试题F:递增三元组
【问题描述】
【输入格式】
【输出格式】
【样例输入】
【样例输出】
27
【代码解析】
三个简单的for循环过程中判大小,然后计数输出即可。
#include<iostream> using namespace std; const int N=1e5+5; int n,str[N][N],sum; int main() { cin >> n; for(int i=0;i<3;i++) for(int j=0;j<n;j++) { cin >> str[i][j]; } for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { if(str[0][i]<str[1][j]) { for(int k=0;k<n;k++) { if(str[1][j]<str[2][k]) { sum++; } } } } } cout << sum << endl; return 0; }
试题G:螺旋折线
【问题描述】
【输入格式】
【输出格式】
输出dis(X, Y)
【样例输入】
0 1
【样例输出】
3
【代码解析】
这里硬模拟的话很难出来,我选择了去找规律,自己大概推导了20分钟就把4个象限的规律统计了出来。虽然初始的点无法满足,但我估计测试点也没有这些吧。下面是具体代码:
#include<iostream> using namespace std; int x,y; int pow(int x,int y) { int sum=1; for(int i=1;i<=y;i++) { sum*=x; } return sum; } int main() { cin >> x >> y; if(x>0&&y>=0) { cout << pow((2*max(x,y)),2)+x-y << endl; } else if(x<=0&&y>0) { cout << pow((-max(-x,y)-y),2)+x-y << endl; } else if(x<0&&y=<0) { cout << pow(2*y,2)-3*y-x << endl; } else if(x>=0&&y<0) { cout << pow(2*max(x,-y),2)+x-y << endl; } return 0; }
试题H:日志统计
【问题描述】
【输入格式】
【输出格式】
按从小到大的顺序输出热帖id。每个id一行。
1
2
3
4
5
6
7
8
9
【输入样例】
7 10 2
0 1
0 10
10 10
10 1
9 1
100 3
100 3
【输出样例】
1
3
【代码解析】
由于数据量比较大,简单的遍历恐怕是不行的。这里选择利用vector来保存时刻,再利用set去重,最终利用尺取法去判断即可。
尺取法
#include<iostream> #include<algorithm> #include<vector> #include<set> using namespace std; #define N 100005 vector<int> t[N]; set<int> s; int n,d,k; bool judge(int x) { int len=t[x].size(); if(len<k) return 0; sort(t[x].begin(),t[x].end()); int l=0,r=0,sum=0; while(l<=r&&r<len) { sum++; if(sum>=k) { if(t[x][r]-t[x][l]<d) return 1; else { l++; sum--; } } r++; } return 0; } int main() { cin>>n>>d>>k; for(int i=0;i<n;i++) { int ts,id; cin>>ts>>id; t[id].push_back(ts); s.insert(id); } for (set<int>::iterator it = s.begin(); it != s.end(); it++) { int x = *it; if(judge(x)) cout<<x<<endl; } return 0; }
试题I:全球变暖
【问题描述】
你有一张某海域NxN像素的照片,".“表示海洋、”#"表示陆地,如下所示:
其中"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。例如上图就有2座岛屿。
由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。
例如上图中的海域未来会变成如下样子:
请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。
【输入格式】
第一行包含一个整数N。 (1 <= N <= 1000)
以下N行N列代表一张海域照片。
照片保证第1行、第1列、第N行、第N列的像素都是海洋。
【输出格式】
一个整数表示答案。
1
2
3
4
5
6
7
8
【输入样例】
7
…
.##…
.##…
…##.
…####.
…###.
…
【输出样例】
1
【代码解析】
利用DFS同时判断初始一共有几个海岛,每个岛会不会被淹没。
#include<iostream> using namespace std; char map[1005][1005]; bool vis_1[1005][1005];//之前是否被访问过 bool vis_2[1005][1005];//该点会不会被淹没 int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};//下,右,上,左 int N; int num; int island; int no,ele=1; bool in(int x,int y) { return x>=0 && x<N && y>=0 && y<N; } void dfs(int x,int y) { vis_1[x][y]=true; for(int i=0;i<4;i++) { int dx=x+dir[i][0]; int dy=y+dir[i][1]; if(in(dx,dy)&&!vis_1[dx][dy]&&!vis_2[x][y]&&map[dx][dy]=='.') { no++; vis_2[x][y]=true; } if(in(dx,dy)&&!vis_1[dx][dy]&&map[dx][dy]=='#') { ele++; dfs(dx,dy); } } } int main() { cin >> N; for(int i=0;i<N;i++) { for(int j=0;j<N;j++) { cin >> map[i][j]; } } for(int i=0;i<N;i++) for(int j=0;j<N;j++) { if(map[i][j]=='#'&&!vis_1[i][j]) { dfs(i,j); num++; if(ele-no>0) { island++; } ele=1; no=0; } } cout << num-island << endl; return 0; }
试题J:乘积最大
【问题描述】
【输入格式】
【输出格式】
一个整数,表示答案。
1
2
3
4
5
6
7
8
9
10
【输入样例】
5 3
-100000
-10000
2
100000
10000
【输出样例】
999100009
1
2
3
4
5
6
7
8
9
10
再例如:
【输入样例】
5 3
-100000
-100000
-2
-100000
-100000
【输出样例】
-999999829
【代码解析】
最后一题,日常混过,留几个大佬的地址吧。
第一个:
https://blog.csdn.net/qq_34202873/article/details/79835790
第二个:
https://blog.csdn.net/jianjianjianjian01/article/details/109502355?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-2.control&dist_request_id=1330147.11419.16180674798676547&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-2.control
最后大家有疑问的话可以评论区留言讨论,有写的不好的地方,不清楚的地方博主还会继续更新,希望大家支持!
这篇关于第九届蓝桥杯C/C++ 大学B组省赛题目及答案解析的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-27Nacos多环境配置学习入门
- 2024-12-27Nacos快速入门学习入门
- 2024-12-27Nacos快速入门学习入门
- 2024-12-27Nacos配置中心学习入门指南
- 2024-12-27Nacos配置中心学习入门
- 2024-12-27Nacos做项目隔离学习入门
- 2024-12-27Nacos做项目隔离学习入门
- 2024-12-27Nacos初识学习入门:轻松掌握服务发现与配置管理
- 2024-12-27Nacos初识学习入门:轻松掌握Nacos基础操作
- 2024-12-27Nacos多环境配置学习入门