P8682题解
题目传送门
参考了一下 楼上的题解
大概思路
因为我们常见的等差数列一般都是有序的,所以我们可以先将数组排个序,这样也方便我们后续的处理。
又因为题目说是让我们求出最短的等差数列。
则我们一定要使得公差尽可能大。
那么完整的等差数列是不可能有数大于
换句话说,
又因为等差数列中每两项的差都可以表示为公差的倍数。
所以等差数列中的每一对
可以得出
其中
根据上面的式子,我们可以得出结论:
最大的公差
则答案就是
根据上面的分析,我们可以写出以下代码。
#include<bits/stdc++.h>
using namespace std;
int a[100005];
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+1+n);
int d=a[n]-a[1];
for(int i=2;i<=n-1;i++) d=__gcd(d,a[i+1]-a[i]);
cout<<(a[n]-a[1])/d+1;
}
但是如果提交上面的代码,你就会发现会 RE一个点,为什么呢?
我们再看回代码就会发现:
在最后一行有一个 (a[n]-a[1])/d+1 ,那要是最后我们求出的
所以,我们可以加上一个特判。
最终代码
#include<bits/stdc++.h>
using namespace std;
int a[100005];
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+1+n);
if(a[1]==a[n]){
cout<<n;
return 0;
}
int d=a[n]-a[1];
for(int i=2;i<=n-1;i++) d=__gcd(d, a[i+1]-a[i]);
cout<<(a[n]-a[1])/d+1;
}