2019 第十届蓝桥杯部分题目整理

早就说着要整理,拖到了不能再拖了。 E 题还有点不清楚,就不写了。。。
包含题目:C: 数列求值、D: 数的分解、F: 特别数的和、G: 完全二叉树的权值、H: 等差数列

试题 C: 数列求值

本题总分: 10 分
【问题描述】 给定数列 1, 1, 1, 3, 5, 9, 17, …,从第 4 项开始,每项都是前 3 项的和。求 第 20190324 项的最后 4 位数字。
【答案提交】 这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一 个 4 位整数(提示:答案的千位不为 0),在提交答案时只填写这个整数,填写 多余的内容将无法得分。

这道题像是斐波那契数列的变形,好像斐波那契的 100 多项就能让 long long 溢出。从别人那里学到了一个巧妙地方法,因为答案要最后四位,那我们保留每个数的最后四位就行了,即每一项对 1e4 取余,或者 1e5 等都可以。写入数列的前三项,从第四项开始,等于前三项的和 对 100000取余。答案对10000取余,得到后四位。后四位进行相加,与前边位的数字是无关的。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
//ios::sync_with_stdio(false);
typedef long long LL;
using namespace std;
const int MAXN = 2e8;
int f[MAXN];
int main() {
	f[0] = f[1] = f[2] = 1;
	for(int i = 3; i <= 20190323; i++) {
		f[i] = (f[i-1] + f[i-2] + f[i-3]) % 100000;
	}
	cout << f[20190323] % 10000;
	return 0;
}

// MAXN 不能超过 2e8 位
// 数列容易溢出,所以要对结果取模
// 因为加法的后4位只和加数后4位有关 
试题 D: 数的分解

本题总分: 10 分
【问题描述】 把 2019 分解成 3 个各不相同的正整数之和,并且要求每个正整数都不包 含数字 2 和 4,一共有多少种不同的分解方法? 注意交换 3 个整数的顺序被视为同一种方法,例如 1000+1001+18 和 1001+1000+18
被视为同一种。
【答案提交】 这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

一个judge函数,判断是否含有2和4;主函数里两层 for 循环,严格保证 i < j < k ,这样就不会有重复的出现。并且 i + j + k 满足题目要求。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
//ios::sync_with_stdio(false);
typedef long long LL;
using namespace std;
const int MAXN = 1e8;
bool judge(int k) {
	while(k) {
		if(k % 10 == 2 || k % 10 == 4) {
			return false;
		}
		k /= 10;
	}
	return true;
}
int main() {
	int ans = 0;
	for(int i = 1; i <= 1999; i++) {
		for(int j = i+1; j <= 1999; j++) {
			int k = 2019 - i - j;
			if(judge(i) * judge(j) * judge(k) != 0 && k > j) {
				ans++;
			}
		}
	}
	cout << ans;
	return 0;
}
// 要保证三个数字不会有重复,应该让它们的顺序一定 
试题 F: 特别数的和

时间限制: 1.0s 内存限制: 256.0MB 本题总分: 15 分
【问题描述】 小明对数位中含有 2、 0、 1、 9
的数字很感兴趣(不包括前导 0),在 1 到 40 中这样的数包括 1、 2、 9、 10 至 32、 39 和 40,共 28
个,他们的和是 574。 请问,在 1 到 n 中,所有这样的数的和是多少?
【输入格式】
输入一行包含两个整数 n。
【输出格式】
输出一行,包含一个整数,表示满足条件的数的和。
【样例输入】
40
【样例输出】
574
【评测用例规模与约定】 对于 20% 的评测用例,
1 ≤ n ≤ 10。 对于 50% 的评测用例, 1 ≤ n ≤ 100。 对于 80% 的评测用例, 1 ≤ n ≤ 1000。
对于所有评测用例, 1 ≤ n ≤ 10000。

这个题出现在这儿就是明显送分了,一个 check 函数检查是否满足条件,满足则主函数加。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
//ios::sync_with_stdio(false);
typedef long long LL;
using namespace std;
const int MAXN = 1e8;
bool check(int x) {
	while(x) {
		int t = x%10;
		if(t == 2 || t == 0 || t == 1 || t == 9) {
			return false;
		}
		x /= 10;
	}
	return true;
}
int n;
int main() {
	LL ans = 0; // 防止溢出 
	scanf("%d", &n);
	for(int i = 1; i <= n; i++) {
		if(check(i) == false) {
			ans += i;
		}
	}
	printf("%d\n", ans);
	return 0;
}

试题 G: 完全二叉树的权值

时间限制: 1.0s 内存限制: 256.0MB 本题总分:20 分
【问题描述】
给定一棵包含 N个节点的完全二叉树,树上每个节点都有一个权值,按从 上到下、从左到右的顺序依次是 A 1 , A 2 , ··· A N ,如下图所示:
在这里插入图片描述
现在小明要把相同深度的节点的权值加在一起,他想知道哪个深度的节点 权值之和最大?如果有多个深度的权值和同为最大,请你输出其中最小的深度。
注:根的深度是 1。
【输入格式】
第一行包含一个整数 N。 第二行包含 N 个整数 A 1 , A 2 , ··· A N 。
【输出格式】
输出一个整数代表答案。
【样例输入】
7 1 6 5 4 3 2 1
【样例输出】
2
【评测用例规模与约定】
对于所有评测用例,
1 ≤ N ≤100000,−100000 ≤ A i ≤ 100000。

试题 H: 等差数列

时间限制: 1.0s 内存限制: 256.0MB 本题总分:20 分
【问题描述】
数学老师给小明出了一道等差数列求和的题目。但是粗心的小明忘记了一 部分的数列,只记得其中 N 个整数。 现在给出这 N个整数,小明想知道包含这 N 个整数的最短的等差数列有几项?
【输入格式】
输入的第一行包含一个整数 N。 第二行包含 N 个整数A 1 ,A 2 ,··· ,A N 。(注意 A 1 ∼ A N 并不一定是按等差数 列中的顺序给出)
【输出格式】
输出一个整数表示答案。
【样例输入】
5 2 6 4 10 20
【样例输出】
10
【样例说明】
包含2、6、4、10、20 的最短的等差数列是 2、4、6、8、10、12、14、16、 18、20。
【评测用例规模与约定】
对于所有评测用例,2 ≤ N ≤ 100000,0 ≤ A i ≤ 10 9 。

这个题有噢,我的代码尾部有几个样例,注意一下。主要就是公差问题,公差不应该是相邻两个数的差的最小值,而是相邻两个数的差的最大公因数。比如数列 3,5,8,10公差应该是1。

#include <iostream>
#include <cstring>
#include <cstdio>
#define inf 0x3f3f3f3f
#include <algorithm>
//ios::sync_with_stdio(false);
typedef long long LL;
using namespace std;
const int MAXN = 1e6;
int n, a[MAXN]; 
int gcd(int a, int b){
	return b == 0 ? a : gcd(b, a%b);	// gcd(b, r) 
}
int main() {
	int minn = inf, sub;
	cin >> n;
	for(int i = 0; i < n; i++) {
		cin >> a[i];
	}
	sort(a, a+n);
	if(a[0] == a[n-1]) {
		cout << n;
		return 0;
	}
	for(int i = 1; i < n; i++) {
		sub = a[i] - a[i-1];
		if(i == 1) {
			minn = sub;
		}
		minn = gcd(sub, minn);
	}
	int ans = (a[n-1] - a[0]) / minn + 1;
	cout << ans;
	return 0;
}
/*
5
2 6 4 10 20
7
7 4 6 2 10 12 20
相邻差取最大公因数 
4
2 4 7 11
特判 每一项都相等 
5
5 5 5 5 5
*/
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值