0
点赞
收藏
分享

微信扫一扫

蓝桥杯——等差数列

晴儿成长记 2022-01-24 阅读 53
题目来源:2019,省赛
知识点:等差数列,最大公约数 (gcd)

输入输出样例
示例

  • 输入
5
2 6 4 10 20
  • 输出
10
  • 样例说明: 包含 2、6、4、10、20 的最短的等差数列是 2、4、6、8、10、12、14、16、 18、20。

题目分析

首先肯定是对数组进行排序。如果要等差数列的项最少,公差应该最大。本题容易陷入一个误区是:将排序后相邻两个数之间的最小差值作为公差。这显然是不对的,可以看下面的一个特例。

因此,真正的公差应该是所有相邻数之间的差值再求最大公约数。上例中 2 与 3 的最大公约数为 1,所以该等差数列的公差就是 1。在知道最小和最大的等差数列的元素时,项数的求法为: ( m a x − m i n ) / d + 1 (max-min)/d+1 (maxmin)/d+1

另外,还有一种特殊情况:公差为0。此时的等差数列所有元素相等,项数就是一开始输入的 n。

问题

每次涉及求gcd、lcm的问题时,手动写函数比较麻烦。对于c++来说,可以使用algorithm里面的函数来直接求解,十分方便。

#include <algorithm>
int main() {
	int a = 2;
	int b = 3;
	cout << __gcd(a, b) << endl;
	cout << a * b / __gcd(a, b) <<endl; //lcm
	return 0;
}

代码

#include <bits/stdc++.h>
using namespace std;

int main() {
	long n;
	long *weight;
	
	cin >> n;
	weight = new long[n]();
	for(long i = 0; i < n; i++) {
		cin >> weight[i];
	}
	
	sort(weight, weight + n);
	
	long* dif = new long[n]();
	bool flag = false;
	for(long i = 0; i < n - 1; i++) {
		dif[i] = weight[i + 1] - weight[i];
		if(dif[i] == 0) {
			flag = true;
			break;
		}
	}
	
	if(flag) {
		cout << n << endl;
		return 0;
	}
	
	long gcd = __gcd(dif[0], dif[1]);
	for(long i = 2; i < n - 1; i++) {
		gcd = __gcd(dif[i], gcd);
	}
	
	long num = (weight[n - 1] - weight[0]) / gcd + 1;
	cout << num << endl;
	
	delete[] weight;
	delete[] dif;
	
	return 0;
}
举报

相关推荐

0 条评论