2020第十一届蓝桥杯大赛软件类省赛第二场C++ B组真题题解

==========================================
2019-2021蓝桥杯C++ B组真题题解:
2019第十届蓝桥杯大赛软件类省赛C++ B组真题题解
2020第十一届蓝桥杯大赛软件类省赛第二场C++ B组真题题解
2021第十二届蓝桥杯大赛软件赛省赛C++ B组真题题解

==========================================

试题 A:门牌制作(5分)

在这里插入图片描述
题目分析:
这道题直接暴力求解就行了
题目代码:

#include <bits/stdc++.h>
using namespace std;
long long res=0;
void cal(int n)
{
	while(n!=0)
	{
		if(n%10==2)res++;
		n/=10;
	}
}
int main()
{
	for(int i=1;i<=2020;i++)
	{
		cal(i);
	}
	cout<<res<<endl;
	return 0;
}

题目答案:

624

试题 B:既约分数(5分)

在这里插入图片描述

题目分析:
只要知道最大公约数gcd(algorithm库里自带gcd函数即 __gcd()),枚举两个数字看是不是既约分数就可以了
题目代码:

#include <bits/stdc++.h>
using namespace std;
int main()
{
	long long res=0;
	for(int i=1;i<=2020;i++)
	{
		for(int j=1;j<=2020;j++)
		{
			if(__gcd(i,j)==1)res++;
		}
	}
	cout<<res<<endl;
	return 0;
}

题目答案:

2481215

试题 C:蛇形填数(10分)

在这里插入图片描述

题目分析:
从图中我们可以知道
我们将斜着的作为一排,第n排坐标之和为n+1,第i排的数字个数为i
所以20行20列坐标之和为40,则是第39排,前面数字是1加到38然后再加20即可
在这里插入图片描述

题目代码:

#include <bits/stdc++.h>
using namespace std;
int main()
{
	int res=0;
	for(int i=1;i<=38;i++)res+=i;
	cout<<res+20<<endl;
	return 0;
}

题目答案:

761

试题 D:跑步锻炼(10分)

在这里插入图片描述
题目分析:
枚举从开始到结束的每一天,注意下面即可
1.检查是否是闰年
2.检查是否是星期一
3.检查是否是开始月初
题目代码:

#include <bits/stdc++.h>
using namespace std;
int months[]={31,28,31,30,31,30,31,31,30,31,30,31};
bool isrun(int a)//是否是闰年
{
	return (a%4==0&&a%100!=0)||(a%400==0);
}
int main()
{
	int day=5;//因为第一天是星期六,所以前一天是星期五
	long long res=0;
	for(int year=2000;year<2020;year++)//枚举年份
	{
		for(int month=0;month<12;month++)//枚举每月
		{
			int monthnum=months[month];
			if(isrun(year)&&month==1)monthnum=29;//如果是闰年则二月是29天
			for(int i=0;i<monthnum;i++)//枚举每一天
			{
				day++;
				day=day%7;
				if(day==1||i==0)res+=2;//如果是月初或者是星期一
				else res+=1;
			}
		}
	}
	for(int month=0;month<9;month++)//枚举2020年 到10月1号
	{
		int monthnum=months[month];
		if(month==1)monthnum=29;
		for(int i=0;i<monthnum;i++)
		{
			day++;
			day=day%7;
			if(day==1||i==0)res+=2;
			else res+=1;
		}
	}
	res+=2;
	day++;
	cout<<res<<endl;
	cout<<day<<endl;
	return 0;
}

题目答案:

8879

试题 E:七段码(15分)

在这里插入图片描述

题目分析:
这道题涉及到枚举+DFS,如果想到的话还是比较容易
枚举就是枚举所有的可能性
DFS就是查找周围是否发亮,如果发亮就发亮总数减一,如果还有发亮还剩余则说明没有连在一起
题目代码:

#include <bits/stdc++.h>
using namespace std;
int diode[7];//二极管是否发亮
int vis[7];//二极管是否访问过
int diode_bright_size;//二极管发亮数量
vector<int> diode_0{1,5};
vector<int> diode_1{0,2,6};
vector<int> diode_2{1,3,6};
vector<int> diode_3{2,4};
vector<int> diode_4{3,5,6};
vector<int> diode_5{0,4,6};
vector<int> diode_6{1,2,4,5};
vector<vector<int>> diodes{diode_0,diode_1,diode_2,diode_3,diode_4,diode_5,diode_6};
void BFS(int n)//访问周围的发亮二级管
{
	vis[n]=1;
	diode_bright_size--;
	for(int i=0;i<diodes[n].size();i++)
	{
		int mid=diodes[n][i];
		if(diode[mid]&&vis[mid]==0)BFS(mid);
	}
}
int main()
{
	int size=1<<7;
	long long tot=0;
	for(int i=1;i<size;i++)//枚举所有可能
	{
		memset(diode,0,sizeof(diode));
		memset(vis,0,sizeof(vis));
		diode_bright_size=0;
		int bright=-1;
		for(int j=0;j<7;j++)
		{
			if((i>>j)&1){
				bright=j;
				diode[j]=1;
				diode_bright_size++;
			}
		}
		if(diode_bright_size==1){//如果只有一个发亮
			tot++;
			continue;
		}
		BFS(bright);
		if(diode_bright_size==0)tot++;
	}
	cout<<tot<<endl;
	return 0;
}

题目答案:

80

试题 F:成绩统计(15分)

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

题目分析:
难点:最后一位要进行四舍五入,因为int是直接把最后一位抹掉
方法:因为计算时会变成小数,但是答案百分位是两位数,所以要多乘100。
我们可以再多乘一位,观察最后一位(也就是舍弃的那位)如果大于等于5则将舍弃前一位加1
题目代码:

#include <bits/stdc++.h>
using namespace std;
int main()
{
	int n,score;
	cin>>n;
	int p_jige=0,p_you=0;
	for(int i=0;i<n;i++)
	{
		cin>>score;
		if(score>=85)p_you++;
		if(score>=60)p_jige++;
	}
	int f_jige=(p_jige*1.0/n)*1000;//多乘一位 方便四舍五入
	int f_you=(p_you*1.0/n)*1000;
	if(f_jige%10>=5)f_jige+=10;//如果最后一位大于等于五 则加1
	if(f_you%10>=5)f_you+=10;
	cout<<f_jige/10<<"%"<<endl;//将最后一位舍掉
	cout<<f_you/10<<"%"<<endl;
}

试题 G:回文日期(20分)

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

题目分析:
这道题就是根据题目进行枚举
我们可以枚举年份(因为是回文,所以每个年份必定只有一个回文日期)
我们判断年份是否是回文日期(比如2019的回文日期是20199102,没有第91月所以不行)
题目代码:

#include <bits/stdc++.h>
using namespace std;
int months[]= {31,28,31,30,31,30,31,31,30,31,30,31};
bool judge(int year) {//判断某个年份是否有回文日期
	int month=0,day=0;
	month+=(year%10)*10;
	year=year/10;
	month+=year%10;
	year=year/10;
	if(month==0||month>12)return false;
	day+=(year%10)*10;
	year=year/10;
	day+=year;
	if(day==0||day>months[month-1])return false;
	return true;
}
int returnres(int year) {//根据年份计算回文日期
	int res=0;
	int mid=year;
	for(int i=0; i<4; i++) {
		res*=10;
		res+=mid%10;
		mid/=10;
	}
	res+=year*10000;
	return res;
}
int main() {
	int N;
	cin>>N;
	int year=N/10000;
	bool isfirst=true;
	for(int i=year; i<=9998; i++) {
		if(judge(i)&&isfirst) {//如果是回文日期,并是第一次
			cout<<returnres(i)<<endl;
			isfirst=false;
		}
		if(judge(i)&&i%100==i/100) {//如果是abab型回文日期
			cout<<returnres(i)<<endl;
			break;
		}
	}
	return 0;
}

试题 H:子串分值和(20分)

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

题目分析:
具体分析我单独写了一个博客
https://blog.csdn.net/qq_46470984/article/details/123652295?spm=1001.2014.3001.5501
题目代码:

#include <bits/stdc++.h>
using namespace std;
int pre[26];
int main()
{
    string s;
    cin>>s;
    long long total=0;
    memset(pre,-1,sizeof(pre)); 
    for(int i=0;i<s.size();i++)
    {
    	total+=(i-pre[s[i]-'a'])*(s.size()-i);
    	pre[s[i]-'a']=i;
	}
    cout<<total;
  return 0;
}

试题 I:平面切分(25分)

在这里插入图片描述

题目分析:
题目代码:

试题 J:字串排序(25分)

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

题目分析:
题目代码:

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

奋斗吧!骚年!

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

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

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

打赏作者

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

抵扣说明:

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

余额充值