文章目录

题解 LGP8682 [蓝桥杯 2019 省 B] 等差数列

由 hycqwq 发布

思路

项数最少等同于公差(记作 $d$)最大。

而由于等差数列的任意两项之差都是公差的倍数(其正确性显然),所以我们只需要求出给出的数两两之差的最大公因数即可。

不过 $O(N^2)$ 这个复杂度嘛……一言难尽!

于是我们来思考优化的办法。

经过不懈的努力,我们发现,其实只需要取相邻的数的最大公因数。为什么呢?因为当 $1 \le a, b, c$ 时,$\gcd(\gcd(a, b), c) = \gcd(a, b, c) < gcd(a, c)$,这是很好理解的,毕竟有了 $b$ 的限制。

那么这样,我们的复杂度就优化到了 $O(N)$。

那我们就开始写代码?(前排提示:题目求的是项数,不是公差)

但是!

你会发现,如果就这样的话,#1 Runtime Error

原因:除 $0$ 错误。

猜猜为什么?如果输入的数都相等,那么算出来的公差不就等于 $0$ 了吗?

于是,加特判吧!如果输入的所有数都相等,那么答案就为 $N$。

引用:

代码

又到了让人喜闻乐见的环节。

#include <iostream>
#include <algorithm>
using namespace std;

int n, a[100005]; 

int gcd(int x, int y)
{
    if (y == 0)
        return x;
    return gcd(y, x % y);
}

int main()
{
    cin >> n;
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    sort(a + 1, a + n + 1);//输入时时无序的,所以要排序
    if (a[1] == a[n])
    {
        //都排完序了第一个和最后一个还是相等
        //肯定是全部都相等
        //于是直接结束!
        cout << n << endl;
        return 0;
    }
    int ans = a[2] - a[1];//初值设为一个公差的若干倍
    for (int i = 3; i <= n; i++)
        ans = gcd(ans, a[i] - a[i - 1]);
    cout << (a[n] - a[1]) / ans + 1 << endl;//求的是项数哦
    return 0;
}

暂无评论

发表评论