蒜头君的数轴
思路:
数论知识,我们要求完美的数轴(间距为只有一个不同),怎样确定哪个作为不同的间距是本题的突破口
1.首先忽略这个不同间距,我们怎样找需要插入多少个点呢,只需找到剩下间距的最大公约数,这个最大公约数就是相同的间距,那么我们用这些间距的总距离除以这个最大公约数再减去已有的点(n-2),就是需要插入的点。
2.设这个不同的间距为i,我们对这个分界点前面的间距求gcd,后面的间距 求gcd,最后两个的再求个gcd。例如(间距为 4 8 3 8 16)
3.枚举每个分界点,找出来最小插入点数即可。
代码
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<map>
#include<queue>
#include<string>
#include<vector>
#include<utility>
#include<algorithm>
using namespace std;
const int MAXN=1e5+5;
const int inf=(1<<30);
int arr[MAXN];
int sum[MAXN],dis[MAXN];
int lgcd[MAXN],rgcd[MAXN];
inline int read(){
int s=0,w=1;
char ch=getchar();
for(;ch>'9' || ch<'0';ch=getchar()){
if(ch=='-') w=-1;
}
for(;ch<='9' && ch>='0';ch=getchar()){
s=(s<<3)+(s<<1)+(ch^'0');
}
return s*w;
}
int gcd(int a,int b){
if(a<b) swap(a,b);
return a%b==0? b : gcd(b,a%b);
}
int main(){
int n;
n=read();
for(int i=1;i<=n;i++){
arr[i]=read();
}
sort(arr+1,arr+n+1);
int sum=arr[n]-arr[1],ans=inf;
for(int i=1;i<n;i++) dis[i]=arr[i+1]-arr[i];
lgcd[1]=dis[1];rgcd[n-1]=dis[n-1];
for(int i=2;i<n;i++)
lgcd[i]=gcd(lgcd[i-1],dis[i]);
for(int i=n-2;i>=1;i--)
rgcd[i]=gcd(rgcd[i+1],dis[i]);
int temp;
for(int i=1;i<n;i++){
if(i==1)
temp=(sum-dis[i])/rgcd[i+1];
else if(i==n-1)
temp=(sum-dis[i])/lgcd[i-1];
else
temp=(sum-dis[i])/gcd(lgcd[i-1],rgcd[i+1]);
ans=min(ans,temp-n+2);
}
printf("%d\n",ans);
return 0;
}