2022年第十三届蓝桥杯大赛C/C++语言B组省赛题解

首先说明:以下题解为本人当时参赛时的解答,请自行检查运行结果的正误
废话不多说,直接上题

试题A:九进制转十进制

在这里插入图片描述

这题没说的,直接简单的“鸭皮”

十进制:2022=2×103+0×102+2×101+2同样得到:
九进制:2×93+0×92+2×91+2×90=(结果)

试题B:顺子日期

在这里插入图片描述

这题出的有点问题,题目中说的123算顺子,但是0到底包不包括在内,题目也没有给出解答,所以,这题如果算0就是14,不算0就是4,最后好像都给算对了。还是有争议的一道题。当时我也没有考虑0,就直接写了个4
答案:4||14

试题C:刷题统计

在这里插入图片描述
这题也没什么好说的,只要给定足够的空间就能拿满分,如果没有考虑到也没关系,部分数据还是能通过,可以拿到一点分数的(比如我……)请自觉将下述代码中的int换成long long

#include <stdio.h>
int main()
{
	int a=0,b=0,n=0,day=0,sum=0;
	scanf("%d%d%d",&a,&b,&n);
	
	while(n){
		day++;
		if(day%6==0||day%7==0){
			sum+=b;
		}
		else{
			sum+=a;
		}
		if(sum>=n){
			break;
		}	
	}
	printf("%d",day);
	return 0;
}

试题D:修剪灌木在这里插入图片描述

这个题虽然说从左到右修建,但是她修建完一圈,从右向左时一样的道理,而树木白天到晚上还会长高,所以用加减法来实现上述问题。晚上做减法,白天长高做加法。再分别讨论是奇数和偶数两种情况,将每次循环的最大值记录下来就可以了。

#include <stdio.h>
#define N 10000
int main()
{
	int x=0,a[N]={0,0,0,0,0,0,0,0,0,0},i,j,k,h,sum=0;
	scanf("%d",&x);
	int b[N]={}; 
	
	for(h=1;h<10;h++){    //外层循环10次 
	
	if(h%2==0){  //超出范围 
			for(j=x-1;j>=0;j--){
				for(i=0;i<x;i++)
		a[i]++;           //实现白天加法 
	    
	    for(k=0;k<x;k++)
	    	if(a[k]>b[k])
	    		b[k]=a[k];
	    		
	    a[j]=0;      //夜晚减法
		
	}				 
	}

//******************************************************************	
	else if(h%2!=0){
		for(j=0;j<x;j++){
		    for(i=0;i<x;i++)
		        a[i]++;           //实现白天加法 
		
		for(k=0;k<x;k++)
	    	if(a[k]>b[k])
	    	   b[k]=a[k];
	    	   
	    a[j]=0;      //夜晚减法 	 
	}
	
	}
}

	for(i=0;i<x;i++)
		printf("%d\n",b[i]-1);      //输出最大值 

	return 0;
	 
}

试题E:X进制减法

在这里插入图片描述
最经典的海伦-秦九韶算法,具体的算法和思想注释在了代码里,能看懂的同学最好了,看不懂没关系,这个题目稍微有点难度。

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
 
typedef long long LL;
 
LL mod=1000000007;
int n,a,b;
int an[100010],bn[100010];
 
int main()
{
	cin>>n;
	cin>>a;
	for(int i=a;i>=1;i--) cin>>an[i];//这里我们需要的是低位对齐进行减法,高位不用管 
	cin>>b;
	for(int i=b;i>=1;i--) cin>>bn[i];//依然是从低位在0处 
	
	LL ans=0;
	for(int i=a;i>=1;i--)//这里不需要取a与b的最高位啊,因为a是严格大于b的,如果位数a<b就违背了这个原则 
	{                    //所以a的长度只能大于等于b 
		ans=(ans*max({2,an[i]+1,bn[i]+1})+an[i]-bn[i])%mod//秦九韶算法,这里算的是差值,所以要加上an[i]-bn[i] 
	}//ans({})这样可以计算多个数的最大值,我们最低为2,最高为最大值加一 
	cout<<ans<<endl;//直接输出即可; 
	
}

试题F:统计子矩阵

在这里插入图片描述
这个题我在考试时候也是最后做出来的,只要思路能清晰,这道题运用普通的暴力求解是可以做出来的。

#include <stdio.h>
int main()
{
	int n,m,i,k,j,r,h,c,b,sum=0,ans=0;
	scanf("%d%d%d",&n,&m,&k);
	
	int a[n][m];
	
	for(i=0;i<n;i++){
		for(j=0;j<m;j++){
			scanf("%d",&a[i][j]);   //输入 
		}
	}
	
	for(i=1;i<=n;i++){   //行       
		for(j=1;j<=m;j++){   //纵    //定义行和列 
		
			for(r=0;r<n;r++){ 
				for(h=0;h<m;h++){   //遍历 
					
					if(r+i<=n&&j+h<=m){
						sum=0;
						for(c=r;c<r+i;c++){
							for(b=h;b<h+j;b++){
								sum+=a[c][b];     //求和 
					
							}
						}
						if(sum<=k) ans++;
					}
					
				}
			}
		}
	}
	
	printf("%d",ans);
	return 0; 
}

试题G:积木画在这里插入图片描述

在这里插入图片描述

此题目是洛谷的类似题目(覆盖墙面),不是很简单。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n;
int mod=1000000007;
int f[1000010][2];
int main(){
    scanf("%d",&n);
    f[0][0]=1;f[1][0]=1;
    for(int i=2;i<=n;i++){
        f[i][0]=(f[i-1][1]+f[i-1][0]+f[i-2][0])%mod;
        f[i][1]=(f[i-1][1]+2*f[i-2][0])%mod;
    }
    cout<<f[n][0];
}


至此,如果上述题目你都做的差不多,省一是稳了
下面的题目就供大家自行学习了,本人在考试时候也做的很垃圾。

在这里插入图片描述
在这里插入图片描述

这题我没做出来!!!!

在这里插入图片描述
在这里插入图片描述
这题的数据应该只能跑起来一部分……

#include <iostream>

using namespace std;

long long cnt=0;

int mod=1000000007;

int  n,m,c=2;

void dfs(int x,int y,int c){
	if(x<0||y<0) return ;
	if(x==0&&y==1&&c==1){
		cnt++;
		cnt=cnt%mod;
		return;
	}
	if(x>0) dfs(x-1,y,c*2);
	if(y>0) dfs(x,y-1,c-1);
}

int main(){
	int m,n;
	cin>>n>>m;
	dfs(n,m,c);
	cout<<cnt<<endl;
}


在这里插入图片描述
在这里插入图片描述

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
 
typedef long long LL;
const int M=200010,N=10;
LL arr[M][N];
int main()
{
	int n;
	cin>>n;
	
	LL sta[10],top=0,mx=0,cnt=0;
	for(int i=0;i<n;i++)
	{
		top=0;
		LL p;
		cin>>p;
		while(p>1) sta[top++]=p,p=sqrt(p/2+1);//把这个数分解存储 
		mx=max(mx,top);//我们要找到最高的那个位置 
		cnt+=top;//一次剪一下,最大修剪次数 
		for(int j=0,k=top-1;k>=0;j++,k--)
		    arr[i][j]=sta[k];//把数的分解结果逆序存储进去 
	}
	for(int i=0;i<mx;i++)
	{
		for(int j=1;j<n;j++)
		{
			if(arr[j][i]==arr[j-1][i]&&arr[j-1][i])//只要他和前面相同,代表可以一起修剪,最大修建次数减减 
			cnt--;
		}
	}
	cout<<cnt<<endl;//直接输出结果即可 
 } 

省赛考完我直接睡了一下午,冷的一批。希望正在准备2023年蓝桥杯的你一定要加油努力,是金子总会发光的!!!!!

  • 9
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Svan.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值