2021第十二届蓝桥杯大赛软件赛省赛C++ B组真题题解

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

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

目录

  • 试题A:空间(5分)
  • 试题B:卡片(5分)
  • 试题C:直线(10分)
  • 试题D:货物摆放(10分)
  • 试题E:路径(15分)
  • 试题F:时间显示(15分)
  • 试题G:砝码称重(20分)
  • 试题H:杨辉三角形(20分)
  • 试题I:双向排序(25分)
  • 试题J:括号序列(25分)

试题A:空间(5分)

2021第十二届蓝桥杯大赛软件赛省赛C++ B组真题题解_第1张图片

题目分析:
1MB=1024*1024B,1B=8位
题目代码:

#include 
using namespace std;
int main()
{
	cout<<256*1024*1024/4<<endl;	
}

题目答案:

67108864

试题B:卡片(5分)

2021第十二届蓝桥杯大赛软件赛省赛C++ B组真题题解_第2张图片

题目分析:
因为从1开始,所以1是用到最多的卡片,我们可以从1枚举,直到有2021个1
题目代码:

#include 
using namespace std;
int tot_1=2021;
void cal(int i)
{
	while(i>0){
		if(i%10==1)tot_1--;
		i=i/10;
	}
}
int main()
{
	int i=1;
	while(1){
		cal(i);
		if(tot_1<=0)break;
		i++;
	}
	cout<<"tot_1:"<<tot_1<<" i:"<<i<<endl;
	return 0;
}

题目答案:

3181

试题C:直线(10分)

2021第十二届蓝桥杯大赛软件赛省赛C++ B组真题题解_第3张图片

题目分析:
枚举所有两个点的情况,然后利用直线公式 y=kx+b 求出k、b,利用结构体将k、b放入set集合,求出唯一直线的数量
注意:
1.k值为0或者无穷需要另外计算
2. b = (X2 * Y1-X1*Y2)/(X2-X1)
题目代码:

#include 
using namespace std;
struct Point {
	int x,y;
	Point() {}
	Point(int xx,int yy):x{xx},y{yy} {}
};
struct Line {
	double k,b;
	Line() {}
	Line(double kk,double bb):k{kk},b{bb} {}
	bool operator<(const Line &l)const
	{
		if(k==l.k)return b<l.b;
		return k<l.k;
	}
};
Point points[425];
set<Line> Lines;
void cal(Point a1,Point a2) {
	if(a2.x==a1.x||a2.y==a1.y)return;
	int bottom=a2.x-a1.x;
	int top=a2.y-a1.y;
	double k=top*1.0/bottom;
	//double b=(a1.y-k*a1.x)*1.0;
	double b=(a2.x*a1.y-a1.x*a2.y)*1.0/bottom;
	Lines.insert(Line(k,b));
}
int main() {
	int n=0;
	for(int x=0; x<20; x++) {
		for(int y=0; y<21; y++) {
			points[n].x=x;
			points[n].y=y;
			n++;
		}
	}
	for(int i=0; i<420; i++) {
		for(int j=i+1; j<420; j++) {
			cal(points[i],points[j]);
		}
	}
	cout<<Lines.size()+20+21<<endl;
}

题目答案:

40257

试题D:货物摆放(10分)

2021第十二届蓝桥杯大赛软件赛省赛C++ B组真题题解_第4张图片

题目分析:
这道题主要考分解质因数
2021041820210418=2*3*3*3*17*131*2857* 5882353
排列组合:35 *(1+2+2+2+3)=2430 【因为有3个3】
题目代码:

#include 
using namespace std;
int main()
{
	long long n;
	cin>>n;
	long long m=n;
	for(long long i=2;i<n/2;i++)
	{
		if(m%i==0)
		{
			cout<<i<<"*";
			m/=i;
			i--;
		}
	}
	return 0;
}

题目答案:

2430

试题E:路径(15分)

2021第十二届蓝桥杯大赛软件赛省赛C++ B组真题题解_第5张图片

题目分析:
方法一:比较简单,相当于枚举的方法
从1到2021进行寻找每个的最短的路径,我想的是多循环几次看结果的变化,但是没想到第一次就是正确的结果
注:n*i/__gcd(n,i) 是求最小公倍数
细节参考:C++ 一行代码解决最大公约数和最小公倍数
题目代码:

#include 
using namespace std;
int num[2022];
void fun(int n)//寻找一个位置的最短路径(更新)
{
	int left=n-21,right=n+21;
	if(n-21<=0)
	{
		left=1;
	}else if(n+21>2021)
	{
		right=2021;
	}
	
	for(int i=left;i<=right;i++)
	{
		num[n]=min(n*i/__gcd(n,i)+num[i],num[n]);	
	}
}
int main()
{
	for(int i=1;i<=2021;i++)num[i]=100000000;//进行初始化
	num[1]=0;
	for(int j=1;j<10;j++)//循环10次看结果
	{
		for(int i=1;i<=2021;i++)
		{
			fun(i);
		}
		cout<<num[2021]<<endl;//查看结果
	}
}

题目答案:

10266837

试题F:时间显示(15分)

2021第十二届蓝桥杯大赛软件赛省赛C++ B组真题题解_第6张图片
2021第十二届蓝桥杯大赛软件赛省赛C++ B组真题题解_第7张图片

题目分析:
只要记清时间的换算单位即可
题目代码:

#include 
using namespace std;
#define Day 86400000
int main()
{
  long int time;
  cin>>time;
  time=time%Day;
  int Hour,minute,second;
  Hour=time/(60*60*1000);
  time=time%(60*60*1000);
  minute=time/(60*1000);
  time=time%(60*1000);
  second=time/1000;
  printf("%02d:%02d:%02d",Hour,minute,second);
  return 0;
}

试题G:砝码称重(20分)

2021第十二届蓝桥杯大赛软件赛省赛C++ B组真题题解_第8张图片
2021第十二届蓝桥杯大赛软件赛省赛C++ B组真题题解_第9张图片

题目分析:
题目代码:

#include 
using namespace std;
int dp[105][100005];
int weight[105];
int main()
{
  int N,sum=0;
  cin>>N;
  for(int i=1;i<=N;i++){
    cin>>weight[i];
    sum+=weight[i];
  }
  for(int i=1;i<=N;i++){
    for(int j=1;j<=sum;j++){
      dp[i][j]=dp[i-1][j];
      if(!dp[i][j]){
        if(weight[i]==j)dp[i][j]=1;
        if(dp[i-1][abs(j-weight[i])])dp[i][j]=1;
        if(dp[i-1][j+weight[i]])dp[i][j]=1;
      }
    }
  }
  long long res=0;
  for(int i=1;i<=sum;i++){
    if(dp[N][i])res++;
  }
  cout<<res<<endl;
  return 0;
}

试题H:杨辉三角形(20分)

2021第十二届蓝桥杯大赛软件赛省赛C++ B组真题题解_第10张图片
2021第十二届蓝桥杯大赛软件赛省赛C++ B组真题题解_第11张图片
题目分析:
题目代码:

#include 
using namespace std;
long long int n;
//求取某个点的值 
long long int C(long long int a, long long int b) {
	long long int ret = 1;
	for (long long int i = a, j = 1; j <= b; i--, j++) {
		ret = ret * i / j;
		if (ret > n) {
			return n + 1;
		}
	}
	return ret;
}
long long getAns(int col)//二分法求某一行是否有等于n的数 
{
	long long l=col,r=max((long long)col,n);
	while(l<r)
	{
		long long mid=(l+r)/2;		
		if(C(mid,col)>=n)
		{
			r=mid;
		}else{
			l=mid+1;
		}
	}
	if(C(l,col)==n)
	{
		return l*(l+1)/2+col+1;//等差数列求和 
	}else{
		return 4e18;
	}
}
int main()
{
	cin>>n;
	if(n==1)
	{
		cout<<"1"<<endl;
		return 0;
	}
	long long res=4e18;
	for(int i=0;i<=20;i++)//枚举20列 
	{
		res=min(res,getAns(i));
	}
	cout<<res<<endl;
}

试题I:双向排序(25分)

2021第十二届蓝桥杯大赛软件赛省赛C++ B组真题题解_第12张图片
2021第十二届蓝桥杯大赛软件赛省赛C++ B组真题题解_第13张图片

题目分析:
题目代码:

试题J:括号序列(25分)

2021第十二届蓝桥杯大赛软件赛省赛C++ B组真题题解_第14张图片

题目分析:
题目代码:

你可能感兴趣的:(蓝桥杯,算法,c++,蓝桥杯)