Greatest Common Divisor 【最小公约数】

版权声明:本文为博主原创文章,转载请注明出处( • ̀ω•́ )✧ https://blog.csdn.net/wangws_sb/article/details/89787061

题目传送门

题目描述

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

解题思路

首先对原数组进行排序并去重,会出现以下两种情况

扫描二维码关注公众号,回复: 6105089 查看本文章
  • 去重后的数组只有一个元素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;
}

猜你喜欢

转载自blog.csdn.net/wangws_sb/article/details/89787061