第十四届蓝桥杯第三期模拟赛 C C++ B组 原题与详解_第十四届蓝桥杯模拟赛(第三期)——c语言版

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

2、2、1 题目描述

2、2、2 题解关键思路与解答

2、3 清理水草

2、3、1 题目描述

2、3、2 题解关键思路与解答

2、4 最大滑雪长度

2、4、1 题目描述

2、4、2 题解关键思路与解答

2、5 序号最小值

2、5、1 题目描述

2、5、2 题解关键思路与解答


标题:第十四届蓝桥杯第三期模拟赛原题与详解

作者:@Ggggggtm

寄语:与其忙着诉苦,不如低头赶路,奋路前行,终将遇到一番好风景

8e7b1dbb544f4fd2bffe7818e2b9d568.png

一、填空题

1、1 找最小全字母十六进制数

1、1、1 题目描述

**题目来源:**第十四届蓝桥杯第三期模拟赛

**题目难度:**简单

**题目描述:**请找到一个大于 2022 的最小数,这个数转换成十六进制之后,所有的数位(不含前导 0)都为字母(A 到 F)。请将这个数的十进制形式作为答案提交。

1、1、2 题解关键思路与解答

在填空题中,我们需要注意的是能省时间就省时间,有时候是没有必要写出一个完全计算该题的代码。 例如本题,我们先看2022的十六进制:22d5e443e9314398ac2f2957533ddd95.png

题目要求所有的数位(不含前导 0)都为字母(A 到 F),那么就是aaa了。直接出答案为:2730。当然,我们也可以写出解题代码。关键就是判断这个数%16是否在10和15之间即可。我们看代码:

bool check_vaild(int x) 
{
	while (x) 
	{
		if (x % 16 >= 10 && x % 16 <= 15)
			;//当满足条件,我们什么也不用做,继续循环即可
		else 
		{
			return false;
		}
		x /= 16;
	}
	return true;
}

int main() 
{
	for (int i = 2023; ; i++) 
	{
		if (check_vaild(i)) 
		{
			cout << i << "\n";
			break; //找到就停止即可
		}
	}

	return 0;
}

1、2 给列命名

1、2、1 题目描述

**题目来源:**第十四届蓝桥杯第三期模拟赛

**题目难度:**简单

**题目描述:**在 Excel 中,列的名称使用英文字母的组合。前 26 列用一个字母,依次为 A 到 Z,接下来 26*26 列使用两个字母的组合,依次为 AA 到 ZZ。请问第 2022 列的名称是什么?

1、2、2 题解关键思路与解答

我们先判断需要几个字母。26*26 < 2022 <26*26*26,很显然我们需要三个字母来表示。我们可以直接算出来答案的。2022-6-26*26-26*26=644(第一次减26是减去的一个字符的,第二次减去26*26是减去两个字母的,第三次减去26*26是减去三个字母中第一个字母为A的情况,也就是到三个字母中第一个字母为B的情况),当我们再减去26*26时,发现结果为-32,我们再往回数32个即可。答案即为:BYT。这道题我们暴力枚举也可。在考试中,能够想到的解决方法即为最优解决方法,尤其是填空题,不必太过追求算法效率。我们看代码:

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

int get(int x, int y, int z) 
{
	return x * 26 * 26 + y * 26 + z;
}

string str(int x, int y, int z) 
{
	string s;
	s += 'A' + x - 1;  //转换为字符形式
	s += 'A' + y - 1;
	s += 'A' + z - 1;
	return s;
}

int main() {
	int n = 2022;

	for (int i = 1; i <= 26; i++)
		for (int j = 1; j <= 26; j++)
			for (int k = 1; k <= 26; k++)
				if (get(i, j, k) == n) 
				{
					cout << str(i, j, k);
					return 0;
				}

	return 0;
}

1、3 日期相等

1、3、1 题目描述

**题目来源:**第十四届蓝桥杯第三期模拟赛

**题目难度:**简单

**题目描述:**对于一个日期,我们可以计算出年份的各个数位上的数字之和,也可以分别计算月和日的各位数字之和。请问从 1900 年 1 月 1 日至 9999 年 12 月 31 日,总共有多少天,年份的数位数字之和等于月的数位数字之和加日的数位数字之和。例如,2022年11月13日满足要求,因为 2+0+2+2=(1+1)+(1+3) 。请提交满足条件的日期的总数量。

1、3、2 题解关键思路与解答

本题答案为:70910。

该题要去看每个年份的年月日,似乎好像有点麻烦。我们不如把1900 年 1 月 1 日至 9999 年 12 月 31 日的日期转换为8位数的数字,再去枚举19000101到99991213之间的每个数字。我们需要先判断该数字是否为合法日期,再去判断年份的数位数字之和是否等于月的数位数字之和加日的数位数字之和。这样做下来似乎并不麻烦,我们看代码。

#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;
int res;

int days[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
bool check_vaild(int year,int month,int day)
{
	if (month == 0 || month > 12)
		return false;

	if (day == 0)
		return false;
	if (month != 2)
	{
		if (day > days[month])
			return false;
	}
	else
	{
		int leap = year % 400 == 0 || year % 4 == 0 && year % 100;

		if (day > days[month] + leap)
			return false;
	}

	return true;
}


int main()
{
	for (int i = 19000101; i <= 99991213; i++)
	{
		int year = i / 10000;
		int month = i % 10000 / 100;
		int day = i % 100;

		if (check_vaild(year, month, day))
		{
			int x=0, y=0, z=0;
			for (int i = 0; i < 4; i++)
			{
				x += year % 10;
				year /= 10;
			}

			while (month)
			{
				y += month % 10;
				month /= 10;
			}

			while(day)
			{
				z += day % 10;
				day /= 10;
			}

			if (x == y + z)
				res++;
		}
	}
    cout<<res;
    return 0;
}

1、4 乘积方案数

1、4、1 题目描述

**题目来源:**第十四届蓝桥杯第三期模拟赛

**题目难度:**简单

**题目描述:**小蓝有 30 个数,分别为:99, 22, 51, 63, 72, 61, 20, 88, 40, 21, 63, 30, 11, 18, 99, 12, 93, 16, 7, 53, 64, 9, 28, 84, 34, 96, 52, 82, 51, 77 。小蓝可以在这些数中取出两个序号不同的数,共有 30*29/2=435 种取法。请问这 435 种取法中,有多少种取法取出的两个数的乘积大于等于 2022 。

1、4、2 题解关键思路与解答

本题答案为:189。

我们这个题应该没有什么好说的,直接暴力枚举即可。我们直接看代码:

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

int nums[31] = { 0, 99, 22, 51, 63, 72, 61, 20, 88, 40,
				21, 63, 30, 11, 18, 99, 12, 93, 16, 7, 53,
				64, 9, 28, 84, 34, 96, 52, 82, 51, 77 };

int main() {

	int res = 0;

	for (int i = 1; i <= 30; i++)
		for (int j = i + 1; j <= 30; j++) {
			if (nums[i] * nums[j] >= 2022) {
				res++;
			}
		}

	cout << res;
	return 0;
}

1、5 最大连通块

1、5、1 题目描述

**题目来源:**第十四届蓝桥杯第三期模拟赛

**题目难度:**简单

题目描述:

110010000011111110101001001001101010111011011011101001111110
010000000001010001101100000010010110001111100010101100011110
001011101000100011111111111010000010010101010111001000010100
101100001101011101101011011001000110111111010000000110110000
010101100100010000111000100111100110001110111101010011001011
010011011010011110111101111001001001010111110001101000100011
101001011000110100001101011000000110110110100100110111101011
101111000000101000111001100010110000100110001001000101011001
001110111010001011110000001111100001010101001110011010101110
001010101000110001011111001010111111100110000011011111101010
011111100011001110100101001011110011000101011000100111001011
011010001101011110011011111010111110010100101000110111010110
001110000111100100101110001011101010001100010111110111011011
111100001000001100010110101100111001001111100100110000001101
001110010000000111011110000011000010101000111000000110101101
100100011101011111001101001010011111110010111101000010000111
110010100110101100001101111101010011000110101100000110001010
110101101100001110000100010001001010100010110100100001000011
100100000100001101010101001101000101101000000101111110001010
101101011010101000111110110000110100000010011111111100110010
101111000100000100011000010001011111001010010001010110001010
001010001110101010000100010011101001010101101101010111100101
001111110000101100010111111100000100101010000001011101100001
101011110010000010010110000100001010011111100011011000110010
011110010100011101100101111101000001011100001011010001110011
000101000101000010010010110111000010101111001101100110011100
100011100110011111000110011001111100001110110111001001000111
111011000110001000110111011001011110010010010110101000011111
011110011110110110011011001011010000100100101010110000010011
010011110011100101010101111010001001001111101111101110011101

小蓝有一个 30 行 60 列的数字矩阵,矩阵中的每个数都是 0 或 1 。如果从一个标为 1 的位置可以通过上下左右走到另一个标为 1 的位置,则称两个位置连通。与某一个标为 1 的位置连通的所有位置(包括自己)组成一个连通分块。请问矩阵中最大的连通分块有多大?

1、5、2 题解关键思路与解答

本题的答案为:148。

当遇到一个坐标可以影响到该坐标的上下左右四个坐标时,我们可以用下面方法来进行求取上下左右的各个坐标:7aae61a42c954b98b688ff319c53e6df.png

本题的方法就是暴搜,不断更新最大值即可,我们结合代码一起理解一下:

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 35, M = 65;

int n = 30, m = 60;
char arr[N][M];

int dx[4] = { -1, 1, 0, 0 }, dy[4] = { 0, 0, -1, 1 };

int dfs(int x, int y) 
{
	int cnt = 1;
	arr[x][y] = '0';

	for (int i = 0; i < 4; i++) 
	{
		int a = x + dx[i], b = y + dy[i];
		if (a <= n && a >= 1 && b <= m && b >= 1 && arr[a][b] == '1') 
		{
			cnt += dfs(a, b);
		}
	}

	return cnt;
}

int main() 
{

	int res = 0;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			cin >> arr[i][j];

	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			if (arr[i][j] == '1')
				res = max(res, dfs(i, j));

	cout << res << "\n";
	return 0;

}

二、编程题

2、1 求星期几

2、1、1 题目描述

**题目来源:**第十四届蓝桥杯第三期模拟赛

**题目难度:**简单

**题目描述:**给定一天是一周中的哪天,请问 n 天后是一周中的哪天?输入第一行包含一个整数 w,表示给定的天是一周中的哪天,w 为 1 到 6 分别表示周一到周六,w 为 7 表示周日。第二行包含一个整数 n。输出一行包含一个整数,表示 n 天后是一周中的哪天,1 到 6 分别表示周一到周六,7 表示周日。对于所有评测用例,1 <= n <= 1000000。

2、1、2 题解关键思路与解答

该题我可称它为“签到题”,分时一定要拿下,否则会吃大亏。我们直接看代码。

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

int main()
{
	int w, n;
	cin >> w >> n;

	if ((w + n) % 7 == 0)
		cout << '7' << endl;
	else
		cout << (w + n) % 7 << endl;

	return 0;
}

2、2 范围覆盖点数

2、2、1 题目描述

**题目来源:**第十四届蓝桥杯第三期模拟赛

**题目难度:**简单

**题目描述:**小蓝负责一块区域的信号塔安装,整块区域是一个长方形区域,建立坐标轴后,西南角坐标为 (0, 0), 东南角坐标为 (W, 0), 西北角坐标为 (0, H), 东北角坐标为 (W, H)。其中 W, H 都是整数。
  他在 n 个位置设置了信号塔,每个信号塔可以覆盖以自己为圆心,半径为 R 的圆形(包括边缘)。
  为了对信号覆盖的情况进行检查,小蓝打算在区域内的所有横纵坐标为整数的点进行测试,检查信号状态。其中横坐标范围为 0 到 W,纵坐标范围为 0 到 H,总共测试 (W+1) * (H+1) 个点。
  给定信号塔的位置,请问这 (W+1)*(H+1) 个点中有多少个点被信号覆盖。

输入第一行包含四个整数 W, H, n, R,相邻整数之间使用一个空格分隔。
       接下来 n 行,每行包含两个整数 x, y,表示一个信号塔的坐标。信号塔可能重合,表示两个信号发射器装在了同一个位置。

输出一行包含一个整数,表示答案。

对于所有评测用例,1 <= W, H <= 100,1 <= n <= 100, 1 <= R <= 100, 0 <= x <= W, 0 <= y <= H。

2、2、2 题解关键思路与解答

本题给出的数据范围较小,我们可以直接采用暴力枚举的方法,时间复杂度度是可以通过的。我们直接枚举每个点位,看是否再信号塔的范围内。计算该点到信号塔的圆心处的距离是否小于等于半径的长度。在计算的时候不必使用sqrt函数进行开根号,直接与半径的平方进行比较即可。sqrt函数反而会损失精度,可能会造成误判。我们看代码。

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

typedef pair<int, int> PII;
#define x first
#define y second

const int N = 110;

int w, h, n, R;
PII a[N];

int main() 
{
	cin >> w >> h >> n >> R;

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

	int res = 0;


![img](https://img-blog.csdnimg.cn/img_convert/fd122ef80030e576f0d316e4d581185e.png)
![img](https://img-blog.csdnimg.cn/img_convert/34fdff019cbfe876934100ea8f28df19.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618668825)**



#include
#include
#include

using namespace std;

typedef pair<int, int> PII;
#define x first
#define y second

const int N = 110;

int w, h, n, R;
PII a[N];

int main()
{
cin >> w >> h >> n >> R;

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

int res = 0;

[外链图片转存中…(img-xssgY2YY-1715886166235)]
[外链图片转存中…(img-2wurzOoe-1715886166235)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

  • 26
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值