LQ0004 等差数列GCD

Posted 海岛Blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LQ0004 等差数列GCD相关的知识,希望对你有一定的参考价值。

题目出处:蓝桥杯2019初赛

题目描述
数学老师给小明出了一道等差数列求和的题目。但是粗心的小明忘记了一部分的数列,只记得其中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。

问题分析
如果给定的数列的每一个数都相同,则公差为0,所以答案为n。这种情况需要特殊处理。
一般情况下,先对给定的数进行排序,然后求出每个数与最小数差值的最大公约数,将这个最大公约数作为等差数列的公差,就可以算出原数列的项数。

程序说明
计算最大公约数一般采用欧几里得算法,用递归函数来实现。因为欧几里得算法就是辗转相除法,递归深度不会太深,还是可用的。递归计算最大公约数函数如下:

int gcd(m, n)

    return n ? gcd(n, m % n) : m;

解题程序中,直接使用C++的STL算法函数__gcd()来计算最大公约数。

AC的C++程序如下:

/* LQ0004 等差数列 */

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100000;
int a[N];

int main()

    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
        cin >> a[i];

    sort(a, a + n);

    int d = 0;  // 公差
    for (int i = 1; i < n; i++)
        d = __gcd(d, a[i] - a[0]);  // 算法函数__gcd()用于计算最大公约数

    if (d) printf("%d\\n", (a[n - 1] - a[0]) / d + 1);
    else printf("%d\\n", n);  // 所有数都相同则公差为0,最多项数为n

    return 0;

以上是关于LQ0004 等差数列GCD的主要内容,如果未能解决你的问题,请参考以下文章

LQ0110 等差素数列无标题

LQ0047 最大比例GCD

Codeforces 1114E(数学+随机算法)

[BZOJ4373]算术天才⑨与等差数列

20200628 T2 等差数列 To Be Continued

BZOJ4373: 算术天才⑨与等差数列