您的位置:首页 > 其它

程序设计:蒜头君的数轴

2018-03-31 22:19 197 查看
今天蒜头君拿到了一个数轴,上边有 nnn 个点,但是蒜头君嫌这根数轴不够优美,想要通过加一些点让它变优美,所谓优美是指考虑相邻两个点的距离,最多只有一对点的距离与其它的不同。
蒜头君想知道,他最少需要加多少个点使这个数轴变优美。

输入格式

输入第一行为一个整数 n(1≤n≤105)n(1 \leq n \leq 10^5)n(1≤n≤105),表示数轴上的点数。
第二行为 nnn 个不重复的整数 x1,x2,...,xn(−109≤xi≤109)x_1,x_2,...,x_n(-10^9 \leq x_i \leq 10^9)x1​,x2​,...,xn​(−109≤xi​≤109),表示这些点的坐标,点坐标乱序排列。

输出格式

输出一行,为一个整数,表示蒜头君最少需要加多少个点使这个数轴变优美。

样例输入

4
1 3 7 15

样例输出

1
#include<cstdio>
#include<cstring>
#include<algorithm>
#define bug(x) printf("%d***\n",x)
#define lbug(x) printf("%lld***\n",x)
typedef long long ll;
using namespace std;
/*
自己的思维还是比较死
一看见删掉一个,我们就想从头到尾,
但是不要忘了预处理这个环节
如果我们可以预处理一段区间的话
我们就可以用2*N换得N*N的效果
实在是巧妙
*/
ll gcd(ll a,ll b){
return b==0?a:gcd(b,a%b);
}
const int maxn=1e5+10;
ll val[maxn],inter[maxn];
ll gcd1[maxn],gcd2[maxn];

int n;
void get_gcd(){
gcd1[0]=inter[2];
gcd1[1]=inter[1];
for(int i=2;i<n;i++){
gcd1[i]=gcd(inter[i],gcd1[i-1]);
}
gcd2
=inter[n-2];
gcd2[n-1]=inter[n-1];
for(int i=n-2;i>=1;i--){
gcd2[i]=gcd(inter[i],gcd2[i+1]);
}
}

int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lld",&val[i]);
}
if(n<=3){
printf("0\n");
return 0;
}
sort(val+1,val+n+1);
for(int i=1;i<n;i++){
inter[i]=val[i+1]-val[i];
}
get_gcd();
ll ans=1,pos=1;
for(int i=1;i<n;i++){
ll tmp=gcd(gcd1[i-1],gcd2[i+1]);
if(tmp>ans){
ans=tmp;
pos=i;
}
}
ll ed=0;
for(int i=1;i<n;i++){
if(i==pos) continue;
ed+=(inter[i]/ans -1);
}
//lbug(ans);
//	bug(pos);
printf("%lld\n",ed);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: