网络知识 娱乐 2022年十三届蓝桥杯国赛将至,来看看去年蓝桥杯C++b组国赛题目如何

2022年十三届蓝桥杯国赛将至,来看看去年蓝桥杯C++b组国赛题目如何

ฅ(๑˙o˙๑)ฅ 大家好, 欢迎大家光临我的博客:面向阿尼亚学习
算法学习笔记系列持续更新中~

阿


在这里插入图片描述

文章目录

  • 一、前言
  • 二、2021年蓝桥杯c++b组国赛真题目录
    • A: 带宽[5分]
      • 思路⭐
      • AC代码🌟
    • B 纯质数 (5分)
      • 思路⭐
      • AC代码🌟
    • C 完全日期 (10分)
      • 思路⭐
      • AC代码🌟
    • D 最小权值 (10分)
      • 思路⭐
      • AC代码🌟
    • E 大写 (15分)
      • 思路⭐
      • AC代码🌟
    • F 123 (15分)
      • 思路⭐
      • AC代码🌟
    • G 异或变换 (20分)
      • 思路⭐
      • AC代码🌟
    • H 二进制问题 (20分)
      • 思路⭐
      • AC代码🌟
    • I 翻转括号序列 (25分)
      • 思路⭐
      • 代码🌟
    • J 异或三角 (25分)
      • 思路⭐
      • 代码🌟
  • 最后


一、前言

填空题都可以做,大多都是模拟题,考一些常见的基本知识。
编程题前几个都可以做
后几个编程题数据大的可以暴力拿数据小的部分分

做题一定要自信,相信自己可以做出了
其实国赛题也没有多难,大不了拿部分分嘛。


二、2021年蓝桥杯c++b组国赛真题目录

A,B,C,D为填空题

A: 带宽[5分]

在这里插入图片描述

思路⭐

bps指的是bit per second(比特每秒)。
B的英文全称为Byte(字节)。
换算关系:1 Byte = 8 bits。
带宽除以8等于每秒网速
故:200Mbps = 200/8 = 25 MB/s。

AC代码🌟

#include 
using namespace std;
int main()
{
	cout<<200/8<<endl;
	return 0;
} 

答案:25

B 纯质数 (5分)

请添加图片描述

思路⭐

根据题意写个check函数判断模拟即可

AC代码🌟

#include
using namespace std;
bool check(int n)
{
	int x=n;
	while(x)
	{
		int y=x%10;
		x=x/10;
		if(y==0||y==1||y==4||y==6||y==8||y==9)
		return false;
	}
	for(int i=2;i<=n/i;i++)
	{
		if(n%i==0)
		return false;
	}
	return true;
}
int main()
{
	int ans=0;
	for(int i=1;i<=20210605;i++)
	{
		if(check(i))
		ans++;
	}
	cout<<ans<<endl;
	return 0;
}

答案:1903

C 完全日期 (10分)

请添加图片描述

思路⭐

蓝桥杯爱考的日期问题
注意闰年的判断即可
四年一润,百年不润,四百年再润
闰年366天

AC代码🌟

#include 
using namespace std;
int a[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};

bool check(int x)
{
	if(x==1||x==4||x==9||x==16||x==25||x==36||x==49||x==64)
		return true;
	return false;
}

int calc(int n)
{
	int s=0;
	while(n)
	{
		s+=n%10;
		n=n/10;
	}
	return s;
}

int main()
{
	int y=2001,m=1,d=1;
	int ans=0;
	while(y<=2021)
	{
		if(check(calc(y)+calc(m)+calc(d)))
		ans++;
		d++;
		int x=a[m];
		
		if(m==2&&(y%4==0&&(y%100!=0||y%400==0)))//判断是否为闰年
		++x;//闰年二月日期加一
		
		if(d>x)
		d=1,m++;
		if(m>12)
		m=1,y++;
	}
	cout<<ans<<endl;
}

答案:977

D 最小权值 (10分)

请添加图片描述

思路⭐

DP问题
状态转移方程见题面
记得开longlong

AC代码🌟

#include 
using namespace std;
long long f[2022];
int main()
{
	memset(f,127,sizeof(f));
	f[0]=0;
	for(int i=1;i<=2021;i++)
	{
		for(int j=0;j<i;j++)
		{
			f[i]=min(f[i],1+2*f[j]+3*f[i-1-j]+j*j*(i-1-j));
		}
	}
	cout<<f[2021]<<endl;
}

答案:2653631372


以下为编程题

E 大写 (15分)

请添加图片描述

思路⭐

大小写问题,
没手也行

AC代码🌟

#include 
#include 

using namespace std;

int main() {
    string s;
    cin >> s;
    for (int i = 0; i < s.size(); i++) {
        if (s[i] <= 'z' && s[i] >= 'a') s[i] = s[i] - 'a' + 'A';
    }
    cout << s;
    return 0;
}

也可以用c++库函数cctype
具体可见常用库函数整理

#include 
#include 
using namespace std;
int main()
{
	string s;
	cin>>s;
	for(int i=0;i<s.length();i++)
	{
		if(islower(s[i]))
		s[i]=toupper(s[i]);
	}
	cout<<s<<endl;
	return 0;
}

F 123 (15分)

请添加图片描述

思路⭐

分块前缀和+二分

AC代码🌟

#include 
using namespace std;
typedef long long LL;
const int N = 1500000;
LL a[N], s[N];

int get(LL x) { // 二分
    int l = 1, r = N;
    while (l < r) {
        int mid = (l + r) >> 1;
        if (x <= a[mid]) r = mid;
        else l = mid + 1;
    }
    return l;
}

int main() {
    for (int i = 1; i < N; i++) {
        a[i] = i + a[i - 1];
        s[i] = a[i] + s[i - 1];
    }

    int T;
 	cin>>T; 
    LL l, r;
    while (T--) {
     	cin>>l>>r;
        int pl = get(l);
        int pr = get(r);

        LL t = s[pr - 1] - s[pl - 1] + a[r - a[pr - 1]] - a[l - 1 - a[pl - 1]];
       cout<<t<<endl;

    }

    return 0;
}

G 异或变换 (20分)

请添加图片描述

思路⭐

肯定有循环节
遇到这种规律题,直接找规律就行,熟练了就属于送分题,除非仍然需要优化
模拟就好

AC代码🌟

#include 
using namespace std;
int n,a[10001],b[10001];
long long t;
char str[10011];
int main()
{
    cin>>n>>t>>str;

    //找循环节
    int c=1;
    while(c<n)
    c=c*2;//周期结束

    t%=c;
    for(int i=1;i<=n;i++)

        if(str[i-1]=='0')
        a[i]=0;
        else
        a[i]=1;
        for(int i=1;i<=t;i++)
        {    
            for(int j=1;j<=n;j++)
        
                b[j]=a[j-1]^a[j];
                memcpy(a,b,sizeof(a));
        
        }
    for(int i=1;i<=n;i++)
        if(a[i])
        cout<<"1"; 
        else
        cout<<"0";

}

}

H 二进制问题 (20分)

请添加图片描述

思路⭐

利用排列组合的方法进行求取,例如对于十进制数字22对应二进制数字10110,可以分别求取位于区间(10110,10100]、(10100,10000]、(10000,00000]这每个区间内满足要求的数字个数,再相加即可。

AC代码🌟

#include 
using namespace std;
int m,a[71];
long long n,c[71][71];

int main()
{
	c[0][0]=1;//求组合数
	for(int i=1;i<=70;i++)
	{
		c[i][0]=1;
		for(int j=1;j<=i;j++)
		{
			c[i][j]=c[i-1][j-1]+c[i-1][j];
		}
	}
	
	cin>>n>>m;
	++n;
	int l=0;
	for(;n;n/=2)
	a[++l]=n%2;
	for(int i=1,j=l;i<j;i++,j--)
	swap(a[i],a[j]);
	int tot=0;
	long long ans=0;
	for(int i=1;i<=l;i++)
		if(a[i]==1)
		ans+=c[l-i][m-tot],++tot;
		cout<<ans<<endl;
	return 0;
}

I 翻转括号序列 (25分)

请添加图片描述

思路⭐

线段树

代码🌟

待补~

J 异或三角 (25分)

请添加图片描述

思路⭐

数位DP

代码🌟

暴力骗分(20%)

#include 
using namespace std;
typedef long long LL;


bool check(int i,int j,int k) {
	int a[3];
	a[0]=i;
	a[1]=j;
	a[2]=k;
	sort(a,a+3);
	return a[0]+a[1]>a[2];
}


int main() {
	int t,n;
	cin>>t;
	while(t--) {
		cin>>n;
		int ans=0;
		for(int i=1; i<=n; i++) {
			for(int j=1; j<=n; j++) {
				int k;
				k=i^j;
				if(k>=1&&k<=n&&check(i,j,k))
					ans++;
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}

最后

莫言真理无穷尽,寸进自有寸进欢

在这里插入图片描述