UPC Contest 1746 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.

题意:

          总共有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;
}

猜你喜欢

转载自blog.csdn.net/ytuyzh/article/details/89765380