省赛将至,咱们看看第十一届蓝桥杯省赛C/C++ B组试题都出了些什么了?知己知彼,百战不殆

Posted 杨枝

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了省赛将至,咱们看看第十一届蓝桥杯省赛C/C++ B组试题都出了些什么了?知己知彼,百战不殆相关的知识,希望对你有一定的参考价值。

🔔文章目录

🍄试题A 门牌制作

💒题目描述

蓝桥云课链接

🌟解题报告

可爱的签到题了,直接枚举,统计2出现的次数

🌻参考代码(C++版本)

#include <bits/stdc++.h>

using namespace std;

int main()

	int cnt = 0;
	for(int i = 1; i <= 2020;i++)
	
		int x = i;
		while(x)
		
			if(x % 10 == 2) cnt++;
			 x /= 10;
		
	
	
	cout << cnt;
	return 0;


🍅试题B 既约分数

💒题目描述

蓝桥云课链接

🌟解题报告

看到求最大公约数,那么欧几里得算法(gcd)应该会在脑海中浮现出来吧~

🌻参考代码(C++版本)

#include <bits/stdc++.h>

using namespace std;

//gcd
int gcd(int a,int b)

	return b ? gcd(b,a%b):a;

int main()

	int cnt = 0;
	for(int i = 1; i <= 2020;i++)
		for(int j = 1; j <=  2020;j++)
		
			if(gcd(i,j) == 1) cnt++;
		
	cout << cnt;
	return 0;

🍆试题C 蛇形填数

💒题目描述

蓝桥云课链接

🌟解题报告

可以很明显的感觉到,这是属于找规律的题了。考试的时候担心自己手画出来的图不标准或者看着别扭,可以直接使用windows自带的画图进行模拟,规律就会十分明显了。

可以很清楚的看到: 1行1列是1
2行2列是5
3行3列是13
4行4列是25


那么:
i i i个数和第 ( i − 1 ) (i-1) i1之间相差 ( i − 1 ) ∗ 4 (i-1)*4 (i1)4

🌻参考代码(C++版本)

#include <bits/stdc++.h>

using namespace std;

int main()

    int ans = 1;
    for(int i = 2;i <= 20; ++i) ans += 4 * (i - 1);
    
    cout<<ans;
    return 0;


🍇试题D 跑步锻炼

💒题目描述

蓝桥云课链接

🌟解题报告

读题不慎,自以为小蓝只是在周一和月初跑步。

我刚才去看了一下泡泡在b站上发的讲解视频,觉得他采用推理的方式解出来也是不错的。我将链接放在这里了哈,需要的小伙伴自行选择呀~


蓝桥杯2020省赛B组填空题解析/第十一届蓝桥杯真题


因为蓝桥杯中对时间处理一直是一块热门,这个题刚好设计了日期处理、平年闰年判断以及星期处理,就拿它作为讲解了。


一、平年闰年的判断
情况①:可以直接整除400
情况②:可以整除4的时候,不能再整除100了,比如1900年这个例子。

 int leap = year % 100 && year % 4 == 0 || year % 400 ==0;

二、月份的处理
因为月份有30天,有31天的,甚至还有28、29的,想系统的枚举是不太方便的,可以考虑打表,然后查询指定月份的天数。

int days[] = 0,31,28,31,30,31,30,31,31,30,31,30,31;

三、本题解题思路
首先:咱们可以 用0 ~ 6表示周一到周天。
其次:用cnt统计2000年1月1日到某年某月某日所经过的天数

因为2000年1月1日是周五,按照咱们上面的规定,
此时能够通过( cnt(此时为0) + 5 )%7也就能够对应上咱们规定的数组中,周五应该有的下标。

其他的星期数,比如2000年1月3号的时候,cnt为2嘛,就可以精准的定位出,这天是周一,其他的每一天,也可以使用类似的方式来确定出是星期几。对于本题而言,只要取模之后是0的日期,就是星期一。

最后了:因为2020年10月1日是孤零零的一天,就单独处理它吧。

🌻参考代码(C++版本)

#include <bits/stdc++.h>

using namespace std;
int days[13] = 0,31,28,31,30,31,30,31,31,30,31,30,31;


bool is_leap(int year)

	return year % 400 == 0 || year % 4 == 0 && year % 100;


int get_day(int year,int month)

	//判断平年闰年
	if(is_leap(year) && month == 2) return days[month] + 1;

	return days[month];


int main()

	//从2000年枚举到2019年吧,然后单独处理2020年的九个月+1天
	
	int cnt = 0;//统计到2000年1月1日的天数
	int ans = 0;
	for(int i = 2000; i <= 2019;i++)
		for(int j = 1; j <= 12;j++)
		
			//枚举这些日子里,月初的时候
			for(int k = 1;k <= get_day(i,j);k++)
			
				//算周几
				int w = (cnt + 5) % 7;
				//如果是月初或者是周一
				if(k == 1 || w == 0) ans += 2;
				else ans ++;
				
				cnt ++;
			
		

	//单独处理2020年的1~9月
	for(int i =1;i <= 9;i++)
	
		for(int k = 1;k <= get_day(2020,i);k++)
			
				//算周几
				int w = (cnt + 5) % 7;
				//如果是月初或者是周一
				if(k == 1 || w == 0) ans += 2;
				else ans ++;

				cnt ++;
			
	
	
	//记得加上10月1号
	ans += 2;
	cout << ans;
    return 0;

实际考试的时候,更加建议去数吧,这种写代码,里面的细节还挺多的,可能得不偿失。看到有用excel解的,我不太懂该怎么操作。


🍈试题E 七段码

💒题目描述

蓝桥云课链接

🌟解题报告

看到连通块,向着并查集的方向思考。但是我自己没有A出来,看了大佬的题解,发现自己太呆了,妄想只是借用一个并查集…
大佬的题解

解题核心:DFS + 并查集

先用 dfs 枚举出二极管的所有亮灭情况;再用 并查集 判断是否只有一个连通块;


1 ~ 7 来代表 a ~ g ;若某两个二极管相邻,那么就在它们之间连一条边

🌻参考代码(C++版本)

#include <bits/stdc++.h>

using namespace std;
const int N = 10;
int ans;//统计结果
int p[N];//存放并查集中,根信息的数组
bool st[N];//记录DFS搜索的状态
int e[N][N];//记录七段码灯管彼此连通的的信息,e[i[[j]表示i和j的连通与否

//补全并查集的核心函数
int find(int x)

	if(p[x] != x) p[x] = find(p[x]);
	return p[x];


//补全DFS函数
void dfs(int u)

	//设置递归结束的边界!
	if(u == 8)
	
		//并查集的初始化
		for (int i = 1; i <= 7; i ++) p[i] = i;
		
		//枚举这些被操作过灯管,检查连通情况
		for(int i = 1; i  <= 7; i++)
			for(int j = 1; j <= 7;j++)
			
				//i是点亮了。j是点亮了。i和j之间是直接联系的
				if(st[i] && st[j] && e[i][j])
				
					//放到一个连通块中
					p[find(i)] = find(j);
				
			
			
		
		int cnt = 0;
		for(int i = 1; i <= 7;i++)
			//当前灯管是亮的,而且形成一个连通块的了
			if(st[i] && p[i] == i) cnt++;

		if(cnt == 1) ans ++;
		
		return ;
	
	
	//递归环节
	st[u] = 1;//打开当前灯管的情况
	dfs(u+1);
	
	st[u] = 0;
	dfs(u+1);//关闭当前灯管的情况
	


int main()

	//初始化1到7号,各个灯管,直接连通的情况
	e[1][2] = e[1][6] = 1;//意思就是,代表a号灯管的的1,和代表b的2号灯管连通,和代表f的6号灯管连通
	e[2][1] = e[2][3] = e[2][7] = 1;
	e[3][2] = e[3][7] = e[3][4] = 1;
	e[4][3] = e[4][5] = 1;
	e[5][4] = e[5][7] = e[5][6] = 1;
	e[6][1] = e[6][7] = e[6][5] = 1;
	e[7][2] = e[7][3] = e[7][5] = e[7][6] = 1;
	
	//从1号灯管开始DFS
	dfs(1);
	
	cout << ans << endl;
	return 0;

然后泡泡的视频里做数的方式咱们也是可以学学的,因为考试的时候,只要能Ac,比啥都好~

🍉试题F 成绩统计

💒题目描述

蓝桥云课链接

🌟解题报告

签到题了。

🌻参考代码(C++版本)

#include <bits/stdc++.h>

using namespace std;
const int N = 10010;
int a[N];
int n;

int main()

	cin >> n;
	for(int i = 0; i <n;i++) cin >>a[i];

	double ans1 = 0, ans2 = 0;
	for(int i = 0; i < n;i++)
	
		if(a[i] >= 60) ans1 += 1;
		if(a[i] >= 85) ans2 += 1;
	
	ans1 =(ans1/n)*100;
	ans2 = (ans2/n)*100;
	printf("%.0f%%\\n%.0f%%",ans1,ans2);
	
	return 0;

🍊试题G 回文日期

💒题目描述

蓝桥云课链接

🌟解题报告

对日期问题的考察,算是蓝桥杯中的一大热门了吧,就像喜欢考察和2相关的题一样。

这个题的考点是对日期的是否合法的判断,处理的时候,小伙伴们的思路不要乱。


先将日期中的年月日取出来,先判断月份。
再月份合法的情况下,处理不是2月情况下的天数是否合法;是2月的情况下,天数是否合法。这种下来,会清晰很多。


🌻参考代码(C++版本)

//可恶,这个破题的数据范围是1000——100000
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

int days[13] = 0,31,28,31,30,31,30,31,31,30,31,30,31;

//判断回文
bool check_vaild(int date)

    //求出年份
    int year = date / 10000;
    //求出月份
    int month = date % 10000 / 100;
    //求出日子
    int day = date % 100;

    //判断月份是否合法
    if(month  == 0 || month > 12) return false;

    if(day == 0 || month != 2 && day > days[month]) return false;

    //处理二月,处理闰年和平年的事儿
    if(month == 2)
    
        int leap = year % 100 && year % 4 == 0 || year % 400 == 0;
        if(day > 28 + leap) return false;//就是在平年大于28,闰年大于29的时候,返回false
    

    return true;



//判断回文+ ABABBABA,直接把上面代码搞下来,多加一个判断

bool check_vaild1(int date)

    //求出年

以上是关于省赛将至,咱们看看第十一届蓝桥杯省赛C/C++ B组试题都出了些什么了?知己知彼,百战不殆的主要内容,如果未能解决你的问题,请参考以下文章

蓝桥杯省赛C++组别大学B组历年题解

蓝桥杯省赛C++组别大学B组历年题解

第十四届蓝桥杯省赛c/c++大学B组题解

2021第十二届蓝桥杯省赛C/C++大学B组正式赛题解

2021第十二届蓝桥杯省赛C/C++大学B组正式赛题解

第十二届蓝桥杯省赛第二场 C/C++ B组 编程题与详解