题目描述
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.
题意:
总共有t组数据,每组数据包括两行,第一行表示有n个数,第二行输入n个数。定义一种操作,这种操作就是将这n个数都加1。问需要多少次操作,让这n个数两两之间的gcd大于1。
思路:
可以想一下,如果只有一个数,如果这个数为1,那么需要1次操作,如果不是1,直接输出n就好。
将原数组排序去重,令b[i]=a[i]-a[i-1],求出b[i](i>0&&i<n)两两之间的gcd,用变量x保存;
在将x与最小的数a[1]求gcd,以及循环寻找x的最小素因子,目的是让最大公约数最小,这样求得的步数就是最小的。
#include<iostream>
#include<algorithm>
using namespace std;
int a[110000];
int gcd(int x,int y)
{
return y==0?x:gcd(y,x%y);
}
int main()
{
int t;
cin>>t;
for(int j=1;j<=t;j++)
{
int n,x;
cin>>n;
a[0]=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
if(n==1)
{
cout<<"Case "<<j<<": ";
if(a[1]==1)
cout<<"1"<<endl;
else
cout<<"0"<<endl;
continue;
}
sort(a+1,a+1+n);
int num=unique(a+1,a+1+n)-a;//去重
x=a[2]-a[1];
for(int i=3;i<num;i++)
{
x=gcd(x,a[i]-a[i-1]);//前一项与后一项做差,并且求出差之间的gcd,用变量x记录
}
cout<<"Case "<<j<<": ";
if(x==1)//如果求出的gcd是1,则表示不可能
{
cout<<"-1"<<endl;
}
else
{
if(gcd(a[1],x)>1) x=gcd(a[1],x);//将求出的x与最小的数进行gcd,缩小需要操作的步数
for(int i=2;i<100000;i++)//缩小操作步数
{
if(x%i==0)
{
x=i;
break;
}
}
if(a[1]%x==0)
cout<<"0"<<endl;
else
cout<<x-a[1]%x<<endl;;
}
}
return 0;
}