第十届蓝桥杯C/C++省赛B组试题+解答

试题A

在这里插入图片描.....述在这里插入图片描述
解答:其实此题可以直接手动运算,无需代码,但需注意若某位选手同时在不同号位均取得最大评分,也只能取该选手一次。

#include <iostream>
using namespace std;

int main(){
	int a[20][5],b[5];
	int k=0,max,sum=0;
	for(int i=0;i<20;i++){
		for(int j=0;j<5;j++){
			cin>>a[i][j];
		}
	}
	for(int j=0;j<5;j++){
		max=a[0][j];
		for(int i=0;i<20;i++){
			for(int t=0;t<5;t++){
				if(i==b[t]){
					i++;		
				}
			}
			if(a[i][j]>max){
				max=a[i][j];
				k=i;
			}	
		}
		sum=sum+max;
		b[j]=k;
	}
	cout<<"-----------\n";
	cout<<"\n";
	cout<<sum;
} 

试题B

在这里插入图片描述
解答:此题可以看做将十进制数转换为26进制数进行运算。

#include <iostream>
using namespace std;

int main(){
	int a,k=0,c=1;
	string str="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	string re="";
	cin>>a;
	int b=a;
	while(b/26!=0){
		b/=26;
		k++;
	}
	b=0;
	for(int i=0;i<k;i++){
		a=a-b*c;
		c=1;
		for(int j=k-i;j>0;j--){
			c=26*c;
		}
		b=a/c;
		re=re+str[b-1];
	}
	int d=a-b*c;
	re=re+str[d-1];
	cout<<re;
	return 0;
} 

试题C

在这里插入图片描述
解答:可以发现和的最后四位数字只与两个加数的最后四位有关,所以可以每次都保留每项的后四位。
最开始是用递归写的,但是递归次数太多会导致爆栈,所以改用循环了。

#include <iostream>
using namespace std;

int a[20190325];
//数组空间太大时,使之成为全局变量 
int main(){
	
	a[1]=a[2]=a[3]=1;
	int n;
	cin>>n;
	for(int i=4;i<=n;i++){
		a[i]=(a[i-1]+a[i-2]+a[i-3])%10000;
	}
	cout<<a[n];
	return 0;
} 

试题D

在这里插入图片描述
解答:

#include <iostream>
using namespace std;

//判断是否包含2和4
int function(int n){
	int a[4];
	int index=0;
	for(int i=0;i<4;i++){
	a[i]=0;
	}
	while(n){
		int t=n%10;
		n=n/10;
		a[index]=t;
		index++;
	}
	for(int i=0;i<4;i++){
		if(a[i]==2||a[i]==4){
			return 0;
		}
	}
	return 1;
}

int main(){
	int x,y,z;
	int sum=0;
	for(int i=1;i<2019;i++){
		for(int j=1+i;j<2019-i;j++){
			int k=2019-i-j;
			if(k>j){
				if(i!=j&&i!=k&&j!=k){
					if(function(i)&&function(j)&&function(k)){
						sum++; 
					}
				}
			}
		}
	}
	cout<<sum;
	return 0;
}

试题E

在这里插入图片描述
maze.txt内容即输入的map数据:

0 1 0 1 0 1 0 1 0 0 1 0 1 1 0 0 1 0 0 1 0 1 0 1 1 0 0 1 0 1 1 0 1 0 0 1 0 0 0 0 1 0 0 0 1 0 1 0 1 0
0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 1 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 1 1 0 0 1 1 0 1 0 0 1 0 1
0 1 1 1 1 0 1 1 0 1 0 0 1 0 0 0 1 0 0 0 0 0 1 1 0 1 0 0 1 0 1 1 1 0 0 0 1 1 0 0 0 0 0 0 0 1 0 0 0 0
0 1 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 1 1 0 1 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1 0 1 0 1 0 1 1 0 0 1 0 1 1
0 0 0 1 1 1 1 1 0 0 0 0 0 0 1 0 1 0 0 0 0 1 0 0 1 0 1 0 0 0 1 0 1 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0
1 1 0 0 1 0 0 0 1 1 0 1 0 1 0 0 0 0 1 0 1 0 1 1 0 0 0 1 1 0 1 0 0 1 1 0 1 0 1 0 1 0 1 1 1 1 0 1 1 1
0 0 0 1 1 0 1 1 0 1 0 1 0 1 0 0 1 0 0 1 0 0 1 0 1 0 0 0 0 0 0 1 0 0 0 1 0 1 0 0 1 1 1 0 0 0 0 0 0 0
1 0 1 0 0 0 0 0 1 0 1 0 0 0 1 0 0 1 1 0 1 0 1 0 1 0 1 1 1 1 1 0 0 1 1 0 0 0 0 1 0 0 0 0 1 1 1 0 1 0
0 0 1 1 1 0 0 0 0 0 1 0 1 0 1 0 0 0 0 1 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 1 0 0 1 1 0 0 0 0 1 0 0 1
1 1 0 0 0 1 1 0 1 0 0 0 0 1 1 1 0 0 1 0 0 0 1 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 0 1 1 0 1 0 0 0
0 0 0 1 0 0 0 0 1 0 0 1 0 0 0 0 0 1 0 1 0 0 1 0 1 0 1 0 1 1 1 0 1 0 0 0 1 0 1 0 1 0 1 0 0 0 0 1 0 1
1 1 1 0 0 1 0 0 1 0 1 0 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 1 0 1 0 1 0 1 0 0 1 0 0 1 0 0 0 1 0 1 0 0
0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 1 0 1 1 0 0 1 1 1 1 0 1 0 0 0 1 1 0 0 0 0 0 1 0 1 0 1 0 1 0 0 0 1 1
1 0 1 0 1 0 1 0 0 1 1 1 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 1 0 1 1 0 0 1 1 1 1 0 1 1 0 1 0 0 0 0 1 0 0 0
1 0 1 0 1 0 1 0 1 0 0 0 0 1 1 0 1 0 1 0 1 0 0 1 0 1 0 0 0 0 1 0 1 0 0 0 0 0 1 1 1 0 1 1 1 0 1 0 0 1
1 0 0 0 0 0 0 0 1 0 1 1 0 0 0 1 0 0 0 0 1 0 1 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0
1 0 1 0 1 0 0 1 0 0 0 0 0 0 0 1 0 1 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 1 1 1 1 0 1 0 1 0 0 1
0 0 1 0 1 0 0 1 0 1 0 1 0 1 1 0 1 0 0 1 0 1 0 1 0 0 0 1 1 0 1 0 1 0 1 1 0 1 1 1 0 0 0 0 1 1 0 1 0 1
1 1 0 0 1 0 1 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 1 0 1 0 0 1 0 1 0 0 0 0 0 1 0 0 0 1 1 1 0 0 0 0 1 0
0 0 0 0 1 0 0 0 1 1 0 0 0 0 1 1 0 1 0 1 1 0 1 0 0 0 0 0 0 1 0 0 1 0 1 0 0 1 0 0 1 0 0 0 0 1 1 1 0 1
1 0 1 0 0 1 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 1 1 1 0 1 1 0 0 1 0 1 1 0 1 0 1 1 0 1 0 1 0 1 0 0 0 0 1 
0 0 1 0 1 0 0 0 0 1 0 0 0 0 1 1 0 1 0 1 0 1 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 1 0 0 0 1 0 0 0 1 0 1 0 1
1 0 1 0 0 0 0 1 0 0 0 1 1 0 0 1 0 0 0 1 0 0 0 0 1 0 1 0 1 0 0 1 0 1 0 1 0 1 0 1 1 1 1 1 0 1 0 0 1 0
0 0 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 1 1 0 0 1 0 1 0 0 1 0 1 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0
1 1 0 1 0 0 0 0 0 0 1 0 0 1 1 1 0 1 1 1 0 0 1 0 0 1 0 0 0 0 1 1 1 0 1 0 0 1 0 1 1 0 1 1 1 0 1 0 0 0
0 0 0 0 0 1 1 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 0 1 0 0 0 0 0 0 1 1 0 0 1 1
1 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 0 0 1 0 0 0 1 1 1 1 1 0 0 0 1 0 1 0 1 0 0 1 0 1 0 0 0 0 0 0 1 0 0 0
1 0 0 0 0 0 1 0 1 0 0 1 0 1 0 0 1 0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 1 0 1 0 1 0 0 0 1 0 1 1 1 0 1 0 0 0
0 0 1 1 1 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 1 1
1 0 0 0 0 0 0 1 1 0 0 1 1 1 0 1 0 1 1 1 0 1 0 0 0 1 0 0 0 1 1 0 1 1 1 0 1 0 1 0 1 1 0 1 1 1 1 0 0 0 

解答:求最短路径,用bfs,使用队列,按照字典由小到大的顺序搜索:DLRU。
最后从出口点根据step数组中的操作向前寻找,可得出全路径。
此题和蓝桥杯 试题集 算法提高中 学霸的迷宫 基本一致。

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
#define N 50
#define M 30

int map[M][N]; //记录地图 
int next_x[4]={1,0,0,-1};//记录移动的x坐标 :下左右上 
int next_y[4]={0,-1,1,0}; //记录移动的y坐标 
int visit[M][N];//记录单元格是否被访问
char step[M][N];//记录由什么操作走到该点 
int n,m;
string str="";

//定义结构体 
struct node{
	int x;
	int y;
};

void bfs(int x,int y){
	node p;
	p.x=x;
	p.y=y;
	//创建队列 
	queue<node> que;
	visit[x][y]=1;
	que.push(p);
	while(que.empty()==0){
		node now=que.front();
		que.pop();
		for(int i=0;i<4;i++){
			node next;
			next.x=now.x+next_x[i];
			next.y=now.y+next_y[i];
			if(next.x>=0&&next.x<n&&next.y>=0&&next.y<m&&visit[next.x][next.y]==0&&map[next.x][next.y]==0){
				switch(i){
					case 0:step[next.x][next.y]='D';break;
					case 1:step[next.x][next.y]='L';break;
					case 2:step[next.x][next.y]='R';break;
					case 3:step[next.x][next.y]='U';break;
				}
				que.push(next);
				visit[next.x][next.y]=1;
			}
		}
	}
}

//从出口单元格向前寻找 
void findWay(){
	int i=n-1,j=m-1;
	
	while(step[i][j]!='S'){
		switch(step[i][j]){
			case 'D':i=i-1;str='D'+str;break;
			case 'R':j=j-1;str='R'+str;break;
			case 'L':j=j+1;str='L'+str;break;
			case 'U':i=i+1;str='U'+str;break;
		}
	} 
	cout<<str<<endl;
} 

int main(){ 
	cin>>n>>m;
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			cin>>map[i][j];
		}
	} 
	//初始化
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			step[i][j]='S';//S表示未经过操作 
		}
	}
	memset(visit,0,sizeof(visit)); 
	bfs(0,0);
	findWay();
	return 0;
}

最后得出的路径为:DDDDRRURRRRRRDRRRRDDDLDDRDDDDDDDDDDDDRDDRRRURRUURRDDDDRDRRRRRRDRRURRDDDRRRRUURUUUUUUULULLUUUURRRRUULLLUUUULLUUULUURRURRURURRRDDRRRRRDDRRDDLLLDDRRDDRDDLDDDLLDDLLLDLDDDLDDRRRRRRRRRDDDDDDRR

试题F

在这里插入图片描述
解答:采用for循环遍历,然后判断是否满足条件。

#include <iostream>
#include <cstring>
using namespace std;

int a[5];

//记录包含的数是哪些
bool include(int x){
	int i=0;
	while(x!=0){
		int r=x%10;
		a[i++]=r;
		x=x/10;
	}
} 

int main(){
	int n,sum=0;
	cin>>n;
	memset(a,-1,sizeof(a));
	for(int i=1;i<=n;i++){
		include(i);
		for(int j=0;j<5;j++){
			判断是否包含2、0、1、9
			if(a[j]==2||a[j]==0||a[j]==1||a[j]==9){
				sum=sum+i;
				break;
			}
		}
	}
	cout<<sum;
}

试题G

在这里插入图片描述
在这里插入图片描述
解答:完全二叉树具有以下特性:
1.每一层的节点个数是2^(n-1)
2.总的节点个数是(2^n)-1
可以根据这两个特性,算出每个深度的权值总和,再取出权值总和最大的深度。

#include <iostream>
#include <cstring>
using namespace std;
#define N 100005

int a[N];
int deep[20]; //记录每一层权值的和 

//求每一层的节点个数 
int partCount(int h){
	int count=1;
	if(h==1){
		count=1;
	}
	else if(h==0){
		count=0;
	}
	else{
		for(int i=1;i<h;i++){
			count=2*count;
		}
	}
	return count;
}


int main(){
	int n,h=1;
	int sum=0;//记录已经计算过的总个数 
	cin>>n;
	memset(deep,0,sizeof(deep));
	for(int i=1;i<=n;i++)
		cin>>a[i];
	while(sum<n){
		for(int i=sum+1;i<=sum+partCount(h);i++){
			deep[h]+=a[i];
		}
		sum=sum+partCount(h);
		h++;
	} 
	//求所有层中最大的权值总和
	int max=deep[1];
	for(int i=1;i<h;i++){
		if(deep[i]>=max){
			max=deep[i];
		}
	}
	//求权值总和最大时所对应的最小的深度
	for(int i=1;i<h;i++){
		if(deep[i]==max){
			cout<<i<<endl;
			break;
		}
	}
	return 0;
}

试题H

在这里插入图片描述
解答:将a数组升序排序后,求数组a所有相邻两数差值的最大公因数。可以先求最前面两个差值的最大公因数,再求此最大公因数和下一个差值的最大公因数,以此类推。

#include <iostream>
#include <algorithm> 
using namespace std;
#define N  100000

int a[N];

//最大公因数:辗转相除法
int gcd(int a,int b){
	int t;
	if(a<b){
		gcd(b,a);
	}
	while(b){
		t=b;
		b=a%b;
		a=t;
	}
	return a;
} 

int main(){
	int n,result;
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>a[i];
	}
	//将a数组由小到大排序 
	sort(a,a+n);
	int min=a[1]-a[0];
	if(min==0){
		result=n;
	}else{
		for(int i=2;i<n;i++){
			min=gcd(min,a[i]-a[i-1]);//min即为最大公约数 
		}
	}
	//根据等差数列的公式:an=a1+(n-1)d求出n的大小
	//an即排序后a数组的最后一位,a1即排序后a数组的第一位 
	result=(a[n-1]-a[0])/min+1; 
	cout<<result<<endl;
}

试题I

在这里插入图片描述
解答:最开始想的是先将数组a降序排序,然后加上前面大的数,减去后面小的数,但是这样做并没有考虑全面。例如,若按照这种做法,当输入值为1,2,3,加号数为0,减号数为2时,结果应为3-2-1=0;但实际上可为3-(1-2)=4;而产生4这样结果的原因是因为后缀表达式可以产生括号,从而使m个减号可以减去1~m个数。所以使结果最大即减去一个最小的数。

#include <iostream>
#include <algorithm>
using namespace std;
#define N 200005
 
int n,m;	
int a[200005];

int main(){
	cin>>n>>m;
	int cnt=0;//负数的个数 
	int sum=0; 
	int k=n+m+1;
	for(int i=0;i<k;i++){
		cin>>a[i];
		sum+=a[i];
		if(a[i]<0) cnt++;
	}
	sort(a,a+k);
	
	//如果数组中没有负数
	if(a[0]>=0){
		//如果减号个数不为0
		if(m){
			sum-=2*a[0];
		} 
	}else{
		//从最小的负数开始枚举,且减号没有用完 ,则减去负数 
		for(int i=0;i<k&&a[i]<0&&m>0;i++){
			sum-=a[i]*2; 
			m--; 
		} 
	}
	cout<<sum<<endl;
	return 0;
	
}

试题J

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
呜呜呜~这题太难了。我没有弄懂,不过可以推荐一个视频,上面有解答:
https://www.bilibili.com/video/av47356111

以上都是在准备蓝桥杯的时候做的,可能有错的地方,欢迎各位大佬指正!

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
2023年的第十四届蓝桥杯 C/C++ 大学生大赛 A 省赛是一个非常重要且具有挑战性的比赛。作为蓝桥杯系列赛事的一部分,这个比赛吸引了全国各地的大学生参与,旨在促进青年学生计算机编程技术的提高,培养他们的创新能力和团队协作精神。 参赛者需要通过线上报名,在规定的时间内上传自己的比赛作品。比赛设置了一系列难度逐渐增加的编程题目,要求选手运用C/C++语言进行编写和实现。这些题目可能涉及算法设计、数据结构、编程基础等方面的知识,考察参赛者的编码能力、解决问题的能力以及在压力下的应变能力。 在比赛中,选手不仅需要具备扎实的编程技术,还需要在有限的时间内迅速分析问题、设计解决方案,并通过编程实现。因此,参赛者需要具备良好的逻辑思维能力、数学基础和编程实践经验。 在省赛中取得好成绩的选手将有机会晋级到全国赛,进一步与全国各地的顶尖选手一较高下,争夺更好的名次和更多的奖品。 参加蓝桥杯 C/C++ 大学生大赛不仅是一次锻炼和展示自己编程能力的机会,还能结识更多志同道合的同学和业界精英,获得丰厚的奖金和荣誉。同时,参赛经历对于大学生未来的学习和职业发展也具有积极的影响。 总之,2023年第十四届蓝桥杯 C/C++ 大学生大赛 A 省赛是一个具有挑战性的比赛,参赛者需要具备扎实的编程技术和解决问题的能力。通过参与比赛,学生可以提升自己的编程能力,拓宽视野,展示个人才华,并为未来的学习和就业打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值