【蓝桥杯冲刺】蓝桥杯11届省赛C++b组真题-填空题

目录

试题A:门牌制作

解题思路:

答案:

试题B:既约分数

解题思路:

答案:

试题C:蛇形填数

解题思路:

答案:

试题D:跑步训练

解题思路:

答案:

试题E:七段码

解题思路:

答案:

写在最后:


试题A:门牌制作

小蓝要为一条街的住户制作门牌号。

这条街一共有 2020 位住户,门牌号从 1 到 2020 编号。

小蓝制作门牌的方法是先制作 0 到 9 这几个数字字符,

最后根据需要将字符粘贴到门牌上,

例如门牌 1017 需要依次粘贴字符 1、 0、 1、 7,

即需要 1 个字符 0, 2 个字符 1, 1 个字符 7。

请问要制作所有的 1 到 2020 号门牌,总共需要多少个字符 2?

解题思路:

直接枚举就行啦:

#include <iostream>
using namespace std;

int main()
{
	int cnt = 0;
	for (int i = 0; i <= 2020; i++) {
		int tmp = i;
		while (tmp) {
			if (tmp % 10 == 2) {
				cnt++;
			}
			tmp /= 10;
		}
	}
	cout << cnt << endl;
	return 0;
}

答案:

624

试题B:既约分数

如果一个分数的分子和分母的最大公约数是1,这个分数称为既约分数。

例如:3 / 4 , 5 / 2 , 1 / 8 , 7 / 1 都是既约分数。

请问,有多少个既约分数,分子和分母都是1 到2020 之间的整数(包括1和2020)?

解题思路:

既约分数其实就是约好的分数,

而约好的分数有一个特点就是,分子分母的最大公约数是1。

#include <iostream>
using namespace std;

//找最大公约数
int gcd(int a, int b) {
	while (b) {
		int c = a % b;
		a = b;
		b = c;
	}
	if (a == 1) return a;
}

int main()
{
	int cnt = 0;
	for (int i = 1; i <= 2020; i++) {
		for (int j = 1; j <= 2020; j++) {
			//如果最大公约数是1,证明是既约分数
			if (gcd(i, j) == 1) {
				cnt++;
			}
		}
	}
	cout << cnt << endl;
	return 0;
}

答案:

2481215

试题C:蛇形填数

如下图所示,小明用从1 开始的正整数“蛇形”填充无限大的矩阵。

 容易看出矩阵第二行第二列中的数是5。

请你计算矩阵中第 20 行第 20 列的数是多少?

解题思路:

我的方法是找规律,很容易看出:

1,5,13 ......

下一个数比上一个数大(i - 1) * 4

#include <iostream>
using namespace std;

int main()
{
	int res = 1;
	for (int i = 2; i <= 20; i++) {
		res += (i - 1) * 4;
	}
	cout << res << endl;
	return 0;
}

答案:

761

试题D:跑步训练

小蓝每天都锻炼身体。

正常情况下,小蓝每天跑 1 千米。

如果某天是周一或者月初(1 日),为了激励自己,小蓝要跑 2 千米。

如果同时是周一或月初,小蓝也是跑 2 千米。

小蓝跑步已经坚持了很长时间,

从 2000 年 1 月 1 日周六(含)到 2020 年10 月 1 日周四(含)。

请问这段时间小蓝总共跑步多少千米?

解题思路:

这是一道经典的日期问题,

最好就是记住日期类问题的模板,

这道题我们先计算到2019年,最后再特殊处理2020年那10个月:

#include <iostream>
using namespace std;

//打表
int day[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

bool is_leap(int year) {
	return (year % 4 == 0 && year % 100 || year % 400 == 0);
}

int get_day(int year, int month) {
	if (is_leap(year) && month == 2) return day[month] + 1;
	else return day[month];
}

int main()
{
	int cnt = 0, res = 0;

	//2000~2019
	for (int i = 2000; i <= 2019; i++) {
		for (int j = 1; j <= 12; j++) {
			for (int k = 1; k <= get_day(i, j); k++) {
				//我们用0~6表示周一到周日,因为2000.1.1是周六,所以+5
				int weekday = (cnt + 5) % 7;
				if (k == 1 || weekday == 0) res += 2;
				else res++;
				cnt++;
			}
		}
	}

	//2020.1.1~2020.9.30
	for (int i = 1; i <= 9; i++) {
		for (int j = 1; j <= get_day(2020, i); j++) {
			int weekday = (cnt + 5) % 7;
			if (j == 1 || weekday == 0) res += 2;
			else res++;
			cnt++;
		}
	}

	//2020.10.1
	res += 2;
	cout << res << endl;
	return 0;
}

细节一定要注意好,否则很容易出错。

答案:

8879

试题E:七段码

小蓝要用七段码数码管来表示一种特殊的文字。

七段码上图给出了七段码数码管的一个图示,

数码管中一共有7 段可以发光的二极管,分别标记为 a,  b,  c,  d,  e,  f,  g。

小蓝要选择一部分二极管(至少要有一个)发光来表达字符。

在设计字符的表达时,要求所有发光的二极管是连成一片的。

例如:b 发光,其他二极管不发光可以用来表达一种字符。

例如:c 发光,其他二极管不发光可以用来表达一种字符。

这种方案与上一行的方案可以用来表示不同的字符,尽管看上去比较相似。

例如:a, b, c, d, e 发光,f, g 不发光可以用来表达一种字符。

例如:b, f 发光,其他二极管不发光则不能用来表达一种字符,因为发光的二极管没有连成一片。

请问,小蓝可以用七段码数码管表达多少种不同的字符?

解题思路:

这道题用dfs + 并查集,

尴尬的是我不会并查集,所以我只能将答案搬运一下,希望对你们能有所帮助:

代码搬运:代码参考

#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;
}

答案:

80

写在最后:

以上就是本篇文章的内容了,感谢你的阅读。

如果喜欢本文的话,欢迎点赞和评论,写下你的见解。

如果想和我一起学习编程,不妨点个关注,我们一起学习,一同成长。

之后我还会输出更多高质量内容,欢迎收看。 

猜你喜欢

转载自blog.csdn.net/Locky136/article/details/129852188
今日推荐