2018CCPC桂林站G Greatest Common Divisor Neko does Maths CodeForces - 1152C 数论欧几里得

题目描述

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,问最少操作几次使得所有数的gcd大于1,或者压根不能使得所有数的gcd大于1。

  思路类似于CF的Neko does Maths CodeForces - 1152C 数论欧几里得,不过这题的k是对n个数而言,但思路是一样的。

  假设b>=a,我们知道gcd(a+k,b+k)是b-a的因子,那么要想知道所有都+k能不能有gcd>1,那就是得看两两数做差,看他们的差的gcd是不是大于1,但是两两做差O(n2)肯定不行。而我们把所有数排序,然后求相邻两个数的差的gcd,就可以了。因为,像三个数a,b,c,他们的差分别是d1,d2,如果d1和d2不互质,那么d1和d1+d2自然也不互质。得出gcd,我们就枚举gcd的因子就好了。

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 const int N=100118;
 5 int a[N];
 6 int main()
 7 {
 8     int t=1,T,n;
 9     scanf("%d",&T);
10     while(t<=T)
11     {
12         scanf("%d",&n);
13         for(int i=0;i<n;i++)
14             scanf("%d",&a[i]);
15         sort(a,a+n);
16         int g=0,ans;
17         for(int i=1;i<n;i++)//并不需要去重,因为gcd(0,x)=x 
18             g=__gcd(g,a[i]-a[i-1]);
19         if(g==1)
20             ans=-1;
21         else if(g==0)//都是同一个数的时候得特判 
22         {
23             if(a[0]==1)
24                 ans=1;
25             else
26                 ans=0;
27         }
28         else
29         {
30             ans=(g-a[0]%g)%g; 
31             for(int i=2;i*i<=g;i++)//枚举因子,找最小答案 
32                 if(g%i==0)
33                 {
34                     ans=min(ans,(i-a[0]%i)%i);
35                     ans=min(ans,(g/i-a[0]%(g/i))%(g/i));
36                 }
37         }
38         printf("Case %d: %d\n",t++,ans);
39     }
40     return 0;
41 }
gcd

猜你喜欢

转载自www.cnblogs.com/LMCC1108/p/10834140.html