题目描述
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.
题目大意
一次操作可以把所有数字+1,问最少进行多少次可以使所有数字的最大公约数大于1,若无论进行多少次操作都不行的话,就输出-1
解题思路
首先对原数组进行排序并去重,会出现以下两种情况
- 去重后的数组只有一个元素a[0],若a[0]=1,那么只需要操作一次,否则不需要操作
- 求排序去重后的数组所有相邻两个元素差值的最大公约数nape,若nape=1,那么输出-1,否则,如果nape和a[0]的最大公约数不等于1,那么将nape=nape和a[0]的最大公约数,然后求nape的最小因子x,x就是最小公约数,若a[0]能整除x,那么不需要进行操作,否则需要进行x-a[0]%x次操作
AC代码
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
using namespace std;
#define io ios::sync_with_stdio(0),cin.tie(0)
#define ms(arr) memset(arr,0,sizeof(arr))
#define mc(a,b) memcpy(a,b,sizeof(b))
#define inf 0x3f3f3f
#define fin freopen("in.txt", "r", stdin)
#define fout freopen("out.txt", "w", stdout)
typedef long long ll;
typedef unsigned long long ULL;
const int mod=1e9+7;
const int N=1e5+100;
int t,n,a[N],nape,temp;
int gcd(int x,int y)
{
return y==0?x:gcd(y,x%y);
}
int main()
{
// fin;
scanf("%d",&t);
for(int k=1;k<=t;k++){
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%d",&a[i]);
sort(a,a+n);
int cnt=unique(a,a+n)-a;
int ans;
if(cnt==1){
if(a[0]==1) ans=1;
else ans=0;
}
else{
nape=a[1]-a[0];;
for(int i=1;i<cnt-1;i++) nape=gcd(nape,a[i+1]-a[i]);
if(nape==1) ans=-1;
else{
if((temp=gcd(nape,a[0]))>1) nape=temp;
for(int i=2;i<100000;i++){
if(nape%i==0){
nape=i;
break;
}
}
if(a[0]%nape==0) ans=0;
else ans=nape-a[0]%nape;
}
}
printf("Case %d: %d\n",k,ans);
}
return 0;
}