==========================================
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分)
题目分析:
题目代码: