开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第25天,点击查看活动详情
数学老师给小明出了一道等差数列求和的题目。但是粗心的小明忘记了一 部分的数列,只记得其中 NN 个整数。
现在给出这 NN 个整数,小明想知道包含这 NN 个整数的最短的等差数列有几项?
输入描述
输入的第一行包含一个整数 NN。
第二行包含 NN 个整数 A_1,A_2,··· ,A_NA1,A2,⋅⋅⋅,AN。(注意 A_1A1 ∼ A_NAN 并不一定是按等差数列中的顺序给出)
其中,2 \leq N \leq 10^5,0 \leq A_i \leq 10^92≤N≤105,0≤Ai≤109。
输出描述
输出一个整数表示答案。
输入输出样例
示例
输入
5
2 6 4 10 20
输出
10
样例说明: 包含 2、6、4、10、20 的最短的等差数列是 2、4、6、8、10、12、14、16、 18、20。
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int a[N];
int n;
int gcd(int a,int b) {
return b ? gcd(b, a % b) : a;
}
int main()
{
scanf("%d",&n);
for(int i = 0;i < n;i ++) scanf("%d",&a[i]);
sort(a,a + n);
int d = 0;
for(int i = 1;i < n;i ++) d = gcd(d, a[i] - a[i - 1]);
if(!d) printf("%d\n",n);
else printf("%d\n",(a[n - 1] - a[0]) / d + 1);
return 0;
}
差数列项数的公式为 ( a n − a 1 ) / d + 1 (a_n - a_1) / d + 1(a
n
−a
1
)/d+1,其中 a n a_na
n
为等差数列的末项,在序列中就是最大值,a 1 a_1a
1
为等差数列的首项,在序列中就是最小值
所以要求序列最短,因为最大值和最小值已经固定,要求的就是公差 d dd 的最大值
因为等差序列可以表示为 a 1 , a 1 + d , a 1 + 2 d , a 1 + 3 d , . . . . , a 1 + n d a_1,a_1 + d,a_1 + 2d,a_1 + 3d,....,a_1 + nda
1
,a
1
+d,a
1
+2d,a
1
+3d,....,a
1
+nd ,可以观察到等差数列的每一项和第一项的差值都是 d dd 的倍数,所以求 d dd 的最大值就是求序列给出的项数差值的最大公约数
代码2
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int a[N];
int main()
{
// 请在此输入您的代码
int n;
cin >> n;
for (int i = 0; i < n; i++) cin >> a[i];
sort(a, a + n);
int minn1 = a[0], minn2 = a[1], maxx = a[n - 1];
int s = minn2 - minn1;
for (int i = 0; i < n- 1; i++) {
s = min(s, a[i + 1] - a[i]);
}
if (s) cout << (maxx - minn1) / s + 1;
else cout << n;
return 0;
}