第十一届蓝桥杯校内模拟赛部分题解

  • 填空题—单位变换
    问题描述
      在计算机存储中,15.125GB是多少MB?
    答案提交
      这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
    题解
    这题就是常识,直接计算就OK了。
#include<bits/stdc++.h>
using namespace std;

int main(){
	double a=15.125;
	cout<<a*1024;
	return 0;
}
  • 填空题—约数个数
    问题描述
      1200000有多少个约数(只计算正约数)。
    答案提交
      这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
    题解
    儿科题,初入门就会,直接码就对了。
#include<bits/stdc++.h>
using namespace std;

int main(){
	int ans=0;
	for(int i=1;i<=1200000;i++){
		if(1200000%i==0){
			ans++;
		}
	}
	cout<<ans<<endl;
	return 0;
}
  • 填空题—叶节点数
    问题描述
      一棵包含有2019个结点的二叉树,最多包含多少个叶结点?
    答案提交
      这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
    题解
    这题也是送分的,就是考二叉树的常识。
n=n0+n1+n2,为使叶子节点数(n0)最多,必须n1最小,设为0,而n0=n2+1,得n2=(2019-1)/2=1009,所以n0=1010。
  • 填空题—数字9
    问题描述
      在1至2019中,有多少个数的数位中包含数字9?
      注意,有的数中的数位中包含多个9,这个数只算一次。例如,1999这个数包含数字9,在计算只是算一个数。
    答案提交
      这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
    题解
    这题也简单,暴力枚举就完事了(去年省赛的弱化题)。
#include<bits/stdc++.h>
using namespace std;
bool fun(int x){
	for(;x;x/=10){//x/10不能正常运行,必须要写成x/=10;
		if(x%10==9){
			return true;
		}
	}
	return false;
}
int main(){
	int ans=0;
	for(int i=1;i<=2019;i++){
		if(fun(i)){
			ans++;
		}
	}
	cout<<ans<<endl;
	return 0;
}

也可以利用STL库来枚举:

#include<bits/stdc++.h>
using namespace std;
bool fun(int x){
	char s[5];
	sprintf(s,"%d",x);
	string str(s);
	return str.find('9')!=string::npos;
}
int main(){
	int ans=0;
	for(int i=1;i<=2019;i++){
		if(fun(i)){
			ans++;
		}
	}
	cout<<ans<<endl;
	return 0;
}

*ps:关于sprintf()的几点说明:
sprintf指的是字符串格式化命令(sprintf 是变参函数)。主要功能是把格式化的数据写入某个字符串中,即发送格式化输出到 string 所指向的字符串。

  • 题目—数位递增的数
    【问题描述】
    一个正整数如果任何一个数位不大于右边相邻的数位,则称为一个数位递增的数,例如1135是一个数位递增的数,而1024不是一个数位递增的数。
    给定正整数 n,请问在整数 1 至 n 中有多少个数位递增的数?
    【输入格式】
    输入的第一行包含一个整数 n。
    【输出格式】
    输出一行包含一个整数,表示答案。
    【样例输入】
    30
    【样例输出】
    26
    【评测用例规模与约定】
    对于 40% 的评测用例,1 <= n <= 1000。
    对于 80% 的评测用例,1 <= n <= 100000。
    对于所有评测用例,1 <= n <= 1000000。
    题解:
    这题也不是很难,依旧是暴力枚举就可以了,可以说是上面一题的强化版。
#include<bits/stdc++.h>
using namespace std;
bool fun(int x){
	int k=0;
	int a[10],b[10];
	while(x){
		a[k++]=x%10;
		x/=10;
	}
	for(int i=0;i<k;i++){
		for(int j=i+1;j<k;j++){
			if(a[i]<a[j]){
				return false;
			}
		}
	}
	return true;
}

int main(){
	long long n;
	cin>>n;
	int ans=0;
	for(int i=1;i<=n;i++){
		if(fun(i)){
			ans++;
		}
	} 
	cout<<ans<<endl;
	return 0;
}

对于这题还有一个方式,就是将数字转换为字符串,用sprintf()函数,本质上依旧是暴力枚举的思想:

#include<bits/stdc++.h>
using namespace std;

void fun(){
	long long n;
	cin>>n;
	int ans=0;
	for(long long i=1;i<=n;i++){
		bool flag=1;
		char s[10];
		sprintf(s,"%lld",i);
		for(int j=1;j<strlen(s);j++){//s[j+1]!=strlen(s)
			if(s[j-1]>s[j]){
				flag=0;
				break;
			}
		}
		if(flag){
			ans++;
		}
	}
	cout<<ans<<endl;
}

int main(){
	while(1){//死循环为测试用
		fun();
	}
	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<bits/stdc++.h>
using namespace std;

void fun(){
	int n,p,q,ans=0;
	cin>>n;
	int *data=new int[n];
	for(int i=0;i<n;i++){
		cin>>data[i];
	}
	for(int i=1;i<n-1;i++){
		p=0;
		for(int j=0;j<i;j++){
			if(data[i]>data[j]){
				p=1;
				break;
			}
		}
		q=0;
		for(int j=i+1;j<n;j++){
			if(data[i]<data[j]){
				q=1;
				break;
			}
		}
		if(p&&q){
			ans++;
		}
	}
	cout<<ans<<endl;
	delete[] data;
}

int main(){
	while(1){//死循环为测试用
		fun();
	}
	return 0;
}

做这道题时,一开始思路错了,以为只要找到比某元素小的元素和大的元素即可,下面是我第一次码的错误代码:

#include<bits/stdc++.h>
using namespace std;
long long a[1005];
void fun(){
	int n,ans=0;
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>a[i];
	}
	sort(a,a+n);
	for(int i=0;i<n;i++){
		if(a[i]!=a[0]&&a[i]!=a[n-1]){
			ans++;
		}
	}
	cout<<ans<<endl;
}
int main(){
	while(1){
		fun();
	}
	return 0;
}
  • 题目—音节判断
    【问题描述】
    小明对类似于 hello 这种单词非常感兴趣,这种单词可以正好分为四段,第一段由一个或多个辅音字母组成,第二段由一个或多个元音字母组成,第三段由一个或多个辅音字母组成,第四段由一个或多个元音字母组成。
    给定一个单词,请判断这个单词是否也是这种单词,如果是请输出yes,否则请输出no。
    元音字母包括 a, e, i, o, u,共五个,其他均为辅音字母。
    【输入格式】
    输入一行,包含一个单词,单词中只包含小写英文字母。
    【输出格式】
    输出答案,或者为yes,或者为no。
    【样例输入】
    lanqiao
    【样例输出】
    yes
    【样例输入】
    world
    【样例输出】
    no
    【评测用例规模与约定】
    对于所有评测用例,单词中的字母个数不超过100。
    题解:
    将单词的辅音标记为0,元音标记为1,那么符合要求的单词形态为0+ 1+ 0+ 1。
    在限定开头必须为0,最后必须为1的情况下,01交替为3次,即前后元素相加结果为1的次数必须为3。
#include<bits/stdc++.h>
using namespace std;

int isyuan(char c){
	return c=='a'||c=='e'||c=='i'||c=='o'||c=='u';//这里用的是判断表达式
}
int work(){
	char word[105];
	gets(word);
	int size=strlen(word);
	if(size<4){
		return 0;
	}
	//开头元音或者辅音结尾,false
	if(isyuan(word[0])||!isyuan(word[size-1])){
		return 0;
	} 
	//新建一个数组进行标记
	int *h=new int[size];
	for(int i=0;i<size;i++){
		if(isyuan(word[i])){
			h[i]=1;
		}else{
			h[i]=0;
		}
	} 
	int cnt=0;
	for(int i=1;i<size;i++){
		if(h[i-1]+h[i]==1){
			cnt++;//当前位置和前一个位置的数相加为1,计数+1 
		}
	}
	delete[] h;
	return cnt==3;//cnt==3是判断表达式,若cnt==3则返回true,否则返回false 
}
int main(){
	while(1){//死循环为测试用
		printf("%s\n",work()?"yes":"no");
	}
	return 0;
}

Tips:关于最后三题,第八题考bfs,第九题考dfs,这两个自己还没学好,最后一题压轴肯定有难度,这里就不多介绍了,就第一题到第七题来说还是比较简单的,第七题稍微有点逻辑上的卡点,但基本上还是以暴力枚举为主,这几题也就是围绕暴力枚举不断变形而已,如果勤加训练并且耐心仔细点都可以拿下这七题的。

发布了131 篇原创文章 · 获赞 58 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_43595030/article/details/105325343