等差数列
题目
数学老师给小明出了一道等差数列求和的题目。
但是粗心的小明忘记了一部分的数列,只记得其中 N 个整数。
现在给出这 N 个整数,小明想知道包含这 N 个整数的最短的等差数列有几项?
输入格式
输入的第一行包含一个整数 N。
第二行包含 N 个整数 A1,A2,···,AN。(注意 A1∼AN 并不一定是按等差数
列中的顺序给出)
输出格式
输出一个整数表示答案。
数据范围
2≤N≤100000,
0≤Ai≤10^9
输入样例:
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>
#include <cstring>
#include <cmath>
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int INF = 1e9;
const int N = 1e5 + 5;
//返回最大公约数
int gcd(int a, int b){
if(b == 0)return a;
return gcd(b, a % b);
}
int n, a[N];
int main()
{
cin>>n;
for(int i = 1; i <= n; i ++)cin>>a[i];
sort(a + 1, a + n + 1);
int d = 0; //最大能够取到的公差
for(int i = 2; i <= n; i ++)d = gcd(d, a[i] - a[i - 1]);
if(d == 0)cout<<n<<'\n';
else cout<< (a[n] - a[1]) / d + 1 <<'\n';
return 0;
}
疑问解答:
问: 为什么d取n个数两两差距最大公约数时,此时等差数列的项数(长度)最小?
答: 因为对于该等差数列我们的首和尾是确定的,分别取n个数中最小值和最大值,否则必然导致等差数列的长度变长或构成的等差数列不合法。那么要该等差数列的长度最小,根据求项数公式,我们就应该让d取得最大值。对于d的取值要满足小于等于这些数两两之间差的最小值,并且d能够整除这些数两两之间差距(d | a[i] - a[i-1]),这样才能保证将两两差距平均分割。则同时满则上述两个要求的就是n个数两两差距的最大公约数。
问: gcd?
答:可以看下这篇文章gcd