等差数列

52 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 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;
}