思路
项数最少等同于公差(记作 $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;
}