Greatest Common Divisor

题目描述

There is an array of length n, containing only positive numbers.
Now you can add all numbers by 1 many times. Please find out the minimum times you need to perform to obtain an array whose greatest common divisor(gcd) is larger than 1 or state that it is impossible.
You should notice that if you want to add one number by 1, you need to add all numbers by 1 at the same time.

 

输入

The first line of input file contains an integer T (1≤T≤20), describing the number of test cases.
Then there are 2×T lines, with every two lines representing a test case.
The first line of each case contains a single integer n (1≤n≤105) described above.
The second line of that contains n integers ranging in [1,109].

 

输出

You should output exactly T lines.
For each test case, print Case d: (d represents the order of the test case) first. Then output exactly one integer representing the answer. If it is impossible, print -1 instead.

 

样例输入

复制样例数据

3
1
2
5
2 5 9 5 7
5
3 5 7 9 11

样例输出

Case 1: 0
Case 2: -1
Case 3: 1

 

提示

Sample 1: You do not need to do anything because its gcd is already larger than 1.
Sample 2: It is impossible to obtain that array.
Sample 3: You just need to add all number by 1 so that gcd of this array is 2.

ps:只有当差值的gcd!=1,才会有解。求出差值gcd后与a[1]求gcd缩小gcd 的范围。从2开始枚举gcd的因子。求出最小因子x。

答案即 x-a[1]%x;

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b){
    if(b==0) return a;
    return gcd(b,a%b);
}
const int N = 1e5+5;
int a[N];
int main()
{
    std::ios::sync_with_stdio(false);
    int t;
    cin>>t;
    int x=0;
    while(t--){
        x++;
        int n;
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>a[i];
        }
        if(n==1) {
            if(a[1]==1) printf("Case %d: 1\n",x);
            else printf("Case %d: 0\n",x);
            continue;
        }
        else {
            sort(a+1,a+1+n);
            int m=unique(a+1,a+1+n)-a;
            int flag=a[2]-a[1];
            for(int i=3;i<m;i++){
                 flag=gcd(a[i]-a[i-1],flag);
                 //cout<<flag<<endl;
            }
            if(flag==1) printf("Case %d: -1\n",x);
            else {
                if(gcd(flag,a[1])>1) flag=gcd(flag,a[1]);
                for(int i=2;i<N;i++){
                    if(flag%i==0) {
                        flag=i;
                        break;
                    }
                }
                if(a[1]%flag==0) printf("Case %d: 0\n",x);
                else printf("Case %d: %d\n",x,flag-a[1]%flag);
            }
        }
    }
    return 0;
}

 

posted on 2019-05-03 17:16  湫叶  阅读(101)  评论(0编辑  收藏  举报

导航