2020蓝桥杯模拟赛真题解析

第一题 单位变换

题目
【问题描述】
在计算机存储中,15.125GB是多少MB?

【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

思路
1G=1024M

答案
15488

第二题 约数个数

题目
【问题描述】
1200000有多少个约数(只计算正约数)。

【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

思路
枚举+检查

参考代码

#include <iostream>

using namespace std;
const int N = 1200000;

int main() {
    int ans = 0;
    for (int i = 1; i <= N; ++i) {
        if (N % i == 0)
            ans++;
    }
    cout << ans << endl;
    return 0;
}

答案:96

第三题 叶结点数

题目
【问题描述】
一棵包含有2019个结点的二叉树,最多包含多少个叶结点?

【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

思路
n=n0+n1+n2,为使叶子节点数(n0)最多,必须n1最小,设为0,而n0=n2+1

得n2=(2019-1)/2=1009

所以n0=1010

答案
1010

补充:二叉树节点计算
(N表示总节点数,N0 N1 N2分别表示度为0,1,2的节点数)
公式一:N=N0+N1+N2;(总结点数与各节点关系)
公式二:N-1=N1+2N2;(边的关系)
联立得:N2+1=N0
可知N2和N0是同步增长的,所以要使N0最大,必须N1最小,即等于零

第四题 数字9

题目
【问题描述】
在1至2019中,有多少个数的数位中包含数字9?
注意,有的数中的数位中包含多个9,这个数只算一次。例如,1999这个数包含数字9,在计算时只是算一个数。

【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

思路:遍历所有数,转化为字符串,用find查找有没有出现9

参考代码:

#include<iostream>
#include<string>
#include<cstdio>
#include<cstdio>
using namespace std;
bool cheak(int i){
	char s[100];
	sprintf(s,"%d",i);
	string str(s);//复制到字符串str中
	return str.find('9')!=-1;
//这里还可以写成
//return str.find('9')!=string::npos;
//string::npos表示字符串不存在的位置
}
int main(){
	string s;
	int ans=0;
	for(int i=9;i<=2019;i++){//遍历所有数
		if(cheak(i)){//检查这个数
			ans++;
		}
	}
	printf("%d",ans);
	return 0;
}

答案:
544

第五题 数位递增的数

题目
【问题描述】
一个正整数如果任何一个数位不大于右边相邻的数位,则称为一个数位递增的数,例如1135是一个数位递增的数,而1024不是一个数位递增的数。
给定正整数 n,请问在整数 1 至 n 中有多少个数位递增的数?

【输入格式】
输入的第一行包含一个整数 n。

【输出格式】
输出一行包含一个整数,表示答案。

【样例输入】
30

【样例输出】
26

【评测用例规模与约定】
对于 40% 的评测用例,1 <= n <= 1000。
对于 80% 的评测用例,1 <= n <= 100000。
对于所有评测用例,1 <= n <= 1000000。

思路:遍历所有数,判断每个数符不符合条件
判断方法:取出i的每个数字依次比较,出现后面前面小的情况立马否认掉

参考代码

#include<cstdio>
int n,ans=0;
bool cheak(int i){
	while(i){
		if(i%10<i/10%10){
			return false;
		}
		i/=10;
	}
	return true;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		if(cheak(i)){
			ans++;
		}
	}
	printf("%d",ans);
	return 0;
} 

第六题 递增三元组

题目
【问题描述】
在数列 a[1], a[2], …, a[n] 中,如果对于下标 i, j, k 满足 0<i<j<k<n+1 且 a[i]<a[j]<a[k],则称 a[i], a[j], a[k] 为一组递增三元组,a[j]为递增三元组的中心。
给定一个数列,请问数列中有多少个元素可能是递增三元组的中心。
【输入格式】
输入的第一行包含一个整数 n。
第二行包含 n 个整数 a[1], a[2], …, a[n],相邻的整数间用空格分隔,表示给定的数列。
【输出格式】
输出一行包含一个整数,表示答案。
【样例输入】
5
1 2 5 3 5
【样例输出】
2
【样例说明】
a[2] 和 a[4] 可能是三元组的中心。
【评测用例规模与约定】
对于 50% 的评测用例,2 <= n <= 100,0 <= 数列中的数 <= 1000。
对于所有评测用例,2 <= n <= 1000,0 <= 数列中的数 <= 10000。
思路:定一个中心,判断前面有没有比他小的数,后面有没有比他大的数,如果都成立则为递增三元组

参考代码

#include<iostream>
using namespace std;
int main(){
	int n,a[1005],ans=0;
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>a[i];
	}
	for(int x=1;x<n-1;x++){
		int flag=0;
		for(int i=x-1;i>=0;i--){
			if(a[i]<a[x]){
				flag++;
				break;
			}
		}
		for(int j=x+1;j<n;j++){
			if(a[j]>a[x]){
				flag++;
				break;
			}
		}
		
		if(flag>=2){
			ans++;
		}
	}
	cout<<ans<<endl;
	return 0;
} 

补充:现代计算器大约运行速度是10^8每秒
高度为h的满二叉树的节点个数为:2^h-1;
叶子节点的个数为:2^(h-1);

第七题 音节判断

题目
【问题描述】
小明对类似于 hello 这种单词非常感兴趣,这种单词可以正好分为四段,第一段由一个或多个辅音字母组成,第二段由一个或多个元音字母组成,第三段由一个或多个辅音字母组成,第四段由一个或多个元音字母组成。
给定一个单词,请判断这个单词是否也是这种单词,如果是请输出yes,否则请输出no。

元音字母包括 a, e, i, o, u,共五个,其他均为辅音字母。

【输入格式】
输入一行,包含一个单词,单词中只包含小写英文字母。

【输出格式】
输出答案,或者为yes,或者为no。

【样例输入】
lanqiao

【样例输出】
yes

【样例输入】
world

【样例输出】
no

【评测用例规模与约定】
对于所有评测用例,单词中的字母个数不超过100。

思路:建立一个整型数组,将所有对应元音音字母标记为1,对应辅音字母标记为0,则要满足条件,元辅交替位置只会出现三次(如果是元辅交替,则接口处的和一定等于1);

参考代码

#include<cstdio>
#include<cstring>
char a[105];
int b[105],ans=0;
int main(){
	scanf("%s",a);
	int len=strlen(a);
	if(len<4){
		printf("no"); 
	}
	for(int i=0;i<len;i++){
		if(a[i]=='a'||a[i]=='e'||a[i]=='i'||a[i]=='o'||a[i]=='u'){
			b[i]=1;//元音位置标记为1 
		}
	}
	for(int i=0;i<len-1;i++){
		if((b[i]+b[i+1]==1)){//判断接口 
			ans++;
		}
	}
	if(ans==3){
		printf("yes");
	}else{
		printf("no");
	}
	return 0;
}

第八题 长草问题

题目
【问题描述】
小明有一块空地,他将这块空地划分为 n 行 m 列的小块,每行和每列的长度都为 1。
小明选了其中的一些小块空地,种上了草,其他小块仍然保持是空地。
这些草长得很快,每个月,草都会向外长出一些,如果一个小块种了草,则它将向自己的上、下、左、右四小块空地扩展,这四小块空地都将变为有草的小块。
请告诉小明,k 个月后空地上哪些地方有草。

【输入格式】
输入的第一行包含两个整数 n, m。
接下来 n 行,每行包含 m 个字母,表示初始的空地状态,字母之间没有空格。如果为小数点,表示为空地,如果字母为 g,表示种了草。
接下来包含一个整数 k。

【输出格式】
输出 n 行,每行包含 m 个字母,表示 k 个月后空地的状态。如果为小数点,表示为空地,如果字母为 g,表示长了草。

【样例输入】
4 5
.g…
……
…g…
……
2

【样例输出】
gggg.
gggg.
ggggg
.ggg.

【评测用例规模与约定】
对于 30% 的评测用例,2 <= n, m <= 20。
对于 70% 的评测用例,2 <= n, m <= 100。
对于所有评测用例,2 <= n, m <= 1000,1 <= k <= 1000。
思路:用搜索,但是注意坑点是防止上一次搜索防止下一次搜索,注意这里的vis[][]标记的用法

运用DFS会出现栈溢出情况
DFS参考代码

#include<cstdio>
char mp[1005][1005];
bool vis[1005][1005];
int vir[4][2]={{-1,0},{0,-1},{1,0},{0,1}};
int m,n,k;
void dfs(int x,int y,int t){
	if(t>=k){
		return;
	}
	for(int i=0;i<4;i++){
		int tx=x+vir[i][0];
		int ty=y+vir[i][1];
		if(tx>=0&&tx<n&&ty>=0&&ty<m){
			mp[tx][ty]='g';
			vis[tx][ty]=true;
			dfs(tx,ty,t+1);
		}
	}
}
int main(){
	scanf("%d %d",&n,&m);
	for(int i=0;i<n;i++){
		scanf("%s",mp[i]);
	}
	scanf("%d",&k);
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			if(mp[i][j]=='g'&&!vis[i][j]){
				dfs(i,j,0);
			}
		}
	}
	for(int i=0;i<n;i++){
		printf("%s\n",mp[i]);
	}
	return 0;
} 

BFS参考代码

#include<iostream>
#include<queue>
using namespace std;
string mp[105];
bool vis[105][105];
int vir[4][2]={{-1,0},{0,-1},{1,0},{0,1}};
struct node{
	int x;
	int y;
	int t;
	node(int tx,int ty,int tt){
		x=tx;
		y=ty;
		t=tt;
	}
};
int main(){
	int n,m,k;
	cin>>n>>m;
	for(int i=0;i<n;i++){
		mp[i].resize(m);
	}
	for(int i=0;i<n;i++){
		cin>>mp[i];
	}
	cin>>k;
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			if(mp[i][j]=='g'&&!vis[i][j]){
				queue<node>s;
				s.push(node(i,j,0));
				while(!s.empty()){
					node pp=s.front();
					/*if(pp.t>=k){
						cout<<pp.t<<' '<<k<<endl; 
						s.pop();
					}*/
					for(int i=0;i<4;i++){
						int tx=pp.x+vir[i][0];
						int ty=pp.y+vir[i][1];
						int tt=pp.t+1;
						if(tx>=0&&tx<n&&ty>=0&&ty<m&&tt<=2){
							s.push(node(tx,ty,tt));
							mp[tx][ty]='g';
							vis[tx][ty]=true;
						}
					}
					s.pop();
				}
				
			}
		}
	}
	for(int i=0;i<n;i++){
		cout<<mp[i]<<endl;
	}
	return 0;
} 

第九题 序列计数

题目

【问题描述】
小明想知道,满足以下条件的正整数序列的数量:
第一项为 n;
第二项不超过 n;
从第三项开始,每一项小于前两项的差的绝对值。

请计算,对于给定的 n,有多少种满足条件的序列。
【输入格式】
输入一行包含一个整数 n。
【输出格式】
输出一个整数,表示答案。答案可能很大,请输出答案除以10000的余数。
【样例输入】
4
【样例输出】
7
【样例说明】
以下是满足条件的序列:
4 1
4 1 1
4 1 2
4 2
4 2 1
4 3
4 4
【评测用例规模与约定】
对于 20% 的评测用例,1 <= n <= 5;
对于 50% 的评测用例,1 <= n <= 10;
对于 80% 的评测用例,1 <= n <= 100;
对于所有评测用例,1 <= n <= 1000。
思路:使用记忆化搜索(通过80%数据)
问题如果从哪一步开始,都是一个规律,必定是递归

记忆化搜索:一般使用标记数组,当搜索如果出现重复状态时我们就可以用记忆搜索,通常DFS中有几个参数,我们的标记数组就是几维,将每个状态存到数组中,下次如果出现了这个状态,就不用再搜下去了,直接返回数组储存的值就好。

参考代码:

#include<cstdio>
#include<cmath>
long long n,ans=0;
long long vis[1005][1005];
long long dfs(int x,int y){
	for(int i=1;i<fabs(x-y);i++){
		if(vis[y][i]!=0){
		    return vis[y][i];
	    }
		ans++;
		ans%=1000;
		vis[y][i]=ans;//记忆 
		dfs(y,i);
	}
	
}
int main(){
	scanf("%lld",&n); 
	for(int i=1;i<=n;i++){//确定第二个数 
		ans++;
		ans%=1000;
		vis[n][i]=ans;//记忆 
		dfs(n,i);//从第二个数开始都是重复子问题 
		
		
	}
	printf("%lld",ans);
} 
发布了160 篇原创文章 · 获赞 13 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Anterior_condyle/article/details/105200347