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;
}