【蓝桥杯冲刺】蓝桥杯13届省赛C++b组真题-A~E题

目录

试题A:九进制转十进制

解题思路

答案

试题B:顺子日期

解题思路

答案

试题C:刷题统计

题解思路

代码

试题D:修建灌木

解题思路

代码

试题E:X进制减法

解题思路

代码

写在最后:


试题A:九进制转十进制

九进制正整数 (2022) _{9} 转换成十进制等于多少?

解题思路

直接转就完了。

#include <iostream>
#include <algorithm>
using namespace std;

int main() {
	cout << 2 * pow(9, 0) + 2 * pow(9, 1) + 0 * pow(9, 2) + 2 * pow(9, 3) << endl;
	return 0;
}

答案

1478

试题B:顺子日期

小明特别喜欢顺子。

顺子指的就是连续的三个数:123 、456 等。

顺子日期指的就是在日期的 yyyymmdd 表示法中,存在任意连续的三位数是一个顺子的日期。

例如 20220123 就是一个顺子日期,因为它出现了一个顺子:123 ;

而 20221023 则不是一个顺子日期,它一个顺子也没有。

小明想知道在整个 2022 年份中,一共有多少个顺子日期。

解题思路

这道题有一定争议,

如果你认为 012 算顺子,那么:

#include <iostream>
#include <string>
using namespace std;

int month[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

int res = 0;

void check(int x) {
	string s = to_string(x);
	for (int i = 0; i + 2 < s.size(); i++) {
		if (s[i] + 1 == s[i + 1] && s[i] + 2 == s[i + 2]) {
			res++;
			return;
		}
	}
}

int main() {
	int year = 2022;
	for (int i = 0; i <= 365; i++) {
		int day = i, mon = 1;
		//算出月份和日期
		while (day > month[mon]) {
			mon++;
			day -= month[mon];
		}
		int y = year * 10000 + mon * 100 + day;
		check(y);//查看是不是顺子
	}
	cout << res << endl;
	return 0;
}

如果你认为 012 不算顺子:

#include <iostream>
#include <string>
using namespace std;

int month[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

int res = 0;

void check(int x) {
	string s = to_string(x);
	for (int i = 0; i + 2 < s.size(); i++) {
		//加一个判断即可
		if (s[i] != '0' && s[i] + 1 == s[i + 1] && s[i] + 2 == s[i + 2]) {
			res++;
			return;
		}
	}
}

int main() {
	int year = 2022;
	for (int i = 0; i <= 365; i++) {
		int day = i, mon = 1;
		//算出月份和日期
		while (day > month[mon]) {
			mon++;
			day -= month[mon];
		}
		int y = year * 10000 + mon * 100 + day;
		check(y);//查看是不是顺子
	}
	cout << res << endl;
	return 0;
}

答案

如果你认为 012 算顺子:

14

如果你认为 012 不算顺子:

4

两个答案都是对的。

试题C:刷题统计

【问题描述】

小明决定从下周一开始努力刷题准备蓝桥杯竞赛。

他计划周一至周五每天做 a 道题目,周六和周日每天做 b 道题目。

请你帮小明计算,按照计划他将在 第几天实现做题数大于等于 n 题?

【输入格式】

输入一行包含三个整数 a , b 和 n 。

【输出格式】

输出一个整数代表天数。

【样例输入】

10 20 99

【样例输出】

8

【评测用例规模与约定】

对于 50 % 的评测用例, 1 ≤ a , b , ≤ 10^{6} .

对于 100 % 的评测用例, 1 ≤ a , b , ≤ 10^{18} .

题解思路

简单模拟即可。

代码

#include <iostream>
using namespace std;

int day[] = { 0, 1, 2, 3, 4, 5, 6 };

int main() {
	int a, b, n;
    scanf("%d %d %d", &a, &b, &n);	
	int i = 0, cnt = 0;
	while (n > 0) {
		i %= 7;
		if (day[i] >= 0 && day[i] <= 4) {
			n -= a;
		}
		else {
			n -= b;
		}
		i++;
		cnt++;
	}
	printf("%d", cnt);
	return 0;
}

试题D:修建灌木

【问题描述】

爱丽丝要完成一项修剪灌木的工作。

有 N 棵灌木整齐的从左到右排成一排。

爱丽丝在每天傍晚会修剪一棵灌木,让灌木的高度变为 0 厘米。

爱丽丝修剪灌木的顺序是从最左侧的灌木开始, 每天向右修剪一棵灌木。

当修剪了最右侧的灌木后,她会调转方向,下一天开始向左修剪灌木。

直到修剪了最左的灌木后再次调转方向。然后如此循环往复。

灌木每天从早上到傍晚会长高 1 厘米,而其余时间不会长高。

在第一天的早晨,所有灌木的高度都是 0 厘米。

爱丽丝想知道每棵灌木最高长到多高。

【输入格式】

一个正整数 N ,含义如题面所述。

【输出格式】

输出 N 行,每行一个整数,第行表示从左到右第 i 棵树最高能长到多高。

【样例输入】

3

【样例输出】

4
2
4

【评测用例规模与约定】

对于 30 % 的数据, ≤ 10 .

对于 100 % 的数据, 1 < ≤ 10000.

解题思路

找规律:

代码

#include <iostream>
#include <algorithm>
using namespace std;

int main() {
	int n = 0;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		printf("%d\n", max(i - 1, n - i) * 2);
	}
	return 0;
}

试题E:X进制减法

【问题描述】

进制规定了数字在数位上逢几进一。

X 进制是一种很神奇的进制,因为其每一数位的进制并不固定!

例如说某种 X 进制数,最低数位为二进制,第二数位为十进制,第三数位为八进制,

则 X 进制数 321 转换为十进制数为 65 。

现在有两个 X 进制表示的整数 A 和 B ,但是其具体每一数位的进制还不确定,

只知道 A 和 B 是同一进制规则,且每一数位最高为 N 进制,最低为二进制。

请你算出 A − B 的结果最小可能是多少。

请注意,你需要保证 A 和 B 在 X 进制下都是合法的,

即每一数位上的数字要小于其进制。

【输入格式】

第一行一个正整数 N ,含义如题面所述。

第二行一个正整数 Ma ,表示 X 进制数 A 的位数。

第三行 Ma 个用空格分开的整数,

表示 X 进制数 A 按从高位到低位顺序各个数位上的数字在十进制下的表示。

第四行一个正整数 Mb ,表示 X 进制数 B 的位数。

第五行 Mb 个用空格分开的整数,

表示 X 进制数 B 按从高位到低位顺序各个数位上的数字在十进制下的表示。

请注意,输入中的所有数字都是十进制的。

【输出格式】

输出一行一个整数,

表示 X 进制数 A − B 的结果的最小可能值转换为十进制后再模 1000000007 的结果。

【样例输入】

11
3
10 4 0
3
1 2 0

【样例输出】

94

【样例说明】

当进制为:最低位 2 进制,第二数位 5 进制,第三数位 11 进制时,减法得到的差最小。

此时 在十进制下是 108 , 在十进制下是 14 ,差值是 94 。

【评测用例规模与约定】

对于 30 % 的数据, N ≤ 10;  Ma , Mb ≤ 8 .

对于 100 % 的数据, 2 ≤ N ≤ 1000;  1 ≤ Ma , Mb ≤ 100000;  A ≥ B .

解题思路

这道题第一件事,是要知道题目中X进制数该怎么转化成10进制,

以题目中给的 321 转化成 65 为例:

最低数位为二进制,第二数位为十进制,第三数位为八进制,

而这里的进制是用来表示:(进制规定了数字在数位上逢几进一

所以,我们是以最低位的进制为基准的,核心思路如下:

八进制位是3,证明十进制的那个位进位了 3 次,才进位完,而十进制那里还剩2:

让 3 * 10 + 2,那么十进制位那里就是32了,

十进制位是 32 个,证明二进制的那个位进位了 32 次,才进位完,而二进制那里还剩1:

让 32 * 2 + 1,最后算出来的就是 65 了。

代码

#include <iostream>
#include <algorithm>
using namespace std;

#define LL long long

const int N = 100010;
LL a[N], b[N], c[N];
LL mod = 1000000007;

int main()
{
	//输入
	LL n = 0;
	scanf("%lld", &n);
	LL ma = 0;
	scanf("%lld", &ma);
	for (LL i = 0; i < ma; i++) {
		scanf("%lld", &a[i]);
	}
	LL mb = 0;
	scanf("%lld", &mb);
	for (LL i = 0; i < mb; i++) {
		scanf("%lld", &b[i]);
	}

	reverse(a, a + ma);
	reverse(b, b + mb);

	//求出每一个位置的进制
	for (int i = 0; i < max(ma, mb); i++) {
		c[i] = max(max(a[i], b[i]) + 1, 2ll);
	}

	//运用刚刚分析的思路,将 A 和 B 的十进制求出 
	LL A = 0, B = 0;
	for (int i = ma - 1; i >= 0; i--) {
		A = ((A * c[i]) + a[i]) % mod;
	}

	for (int i = mb - 1; i >= 0; i--) {
		B = ((B * c[i]) + b[i]) % mod;
	}

	printf("%lld\n", (A - B + mod) % mod);

	return 0;
}

写在最后:

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

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

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

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

猜你喜欢

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