【計蒜客 A1633 --- 程序設計:蒜頭君的數軸】gcd

【計蒜客 A1633 --- 程序設計:蒜頭君的數軸】gcd

題目來源:點擊進入【計蒜客 A1633 — 程序設計:蒜頭君的數軸】

Description

今天蒜頭君拿到了一個數軸,上邊有 n 個點,但是蒜頭君嫌這根數軸不夠優美,想要通過加一些點讓它變優美,所謂優美是指考慮相鄰兩個點的距離,最多隻有一對點的距離與其它的不同。

蒜頭君想知道,他最少需要加多少個點使這個數軸變優美。

Input

輸入第一行爲一個整數 n(1≤n≤105),表示數軸上的點數。

第二行爲 n 個不重複的整數 x1,x2,…,xn (−109≤xi≤109),表示這些點的座標,點座標亂序排列。

Output

輸出一行,爲一個整數,表示蒜頭君最少需要加多少個點使這個數軸變優美。

Sample Input

4
1 3 7 15

Sample Output

1

解題思路:

首先我們分析題意:所謂的優美實際上是除了一對點之外,使其他相鄰點距離相同。
那麼既然是相同,而且要使加入的點最少,所以我們需要考慮除了某一對以外其他點之間距離的最大公約數,這樣只需要在公約數處加入點即可。
當然我們還要排除那唯一一對的情況。所以我們可以通過兩個數組分別記錄從左到i和從右到i的最大公約數,通過最大公約數,我們可以得到左右兩邊最後一共有多少點,減去原本就有的點即需要加入的點。然後遍歷這個i,使左右兩邊需要加入的點最少。

AC代碼(C++):

#include <iostream>
#include <algorithm>
#define SIS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define endl '\n'
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int MAXN = 1e5+5;
int arr[MAXN],l[MAXN],r[MAXN];

int gcd(int a, int b) 
{
    if (a<b) swap(a,b);
    return (a%b == 0) ? b : gcd(b,a%b);
}

int main()
{
    SIS;
    int n,ans=inf;
    cin >> n;
    for(int i=0;i<n;i++) cin >> arr[i];
    sort(arr,arr+n);
    int sum=arr[n-1]-arr[0];
    l[1]=arr[1]-arr[0];
    r[n-2]=arr[n-1]-arr[n-2];
    for(int i=2;i<n;i++)
        l[i]=gcd(l[i-1],arr[i]-arr[i-1]);
    for(int i=n-3;i>=0;i--)
        r[i]=gcd(r[i+1],arr[i+1]-arr[i]);
    ans=min(ans,(sum-arr[1]+arr[0])/r[1]-n+2);
    ans=min(ans,(sum-arr[n-1]+arr[n-2])/l[n-2]-n+2);
    for(int i=1;i<n-2;i++)
        ans=min(ans,(sum-arr[i+1]+arr[i])/gcd(l[i],r[i+1])-n+2);
    cout << ans << endl;
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章