zoukankan      html  css  js  c++  java
  • 2018CCPC桂林站G 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.

       题目大意:每次操作都给数组的所有数同时+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
    ",t++,ans);
    39     }
    40     return 0;
    41 }
    gcd
  • 相关阅读:
    GYM 101128 J.Saint John Festival(求凸包是否包含点)
    GYM 101128 F.Landscaping(网络流)
    ACM ICPC 2017 Warmup Contest 2 I. Integral Polygons(计算几何+动态规划)
    ACM ICPC 2017 Warmup Contest 1 A. Artwork(逆向+dfs+并查集)
    51nod 1225 余数之和(数论)
    51nod 1397 最大二分图(图论+思维)
    51nod 1444 破坏道路(任意两点最短路径)
    网络流24题——孤岛营救问题(状压+分层图)
    ACM 竞赛高校联盟 练习赛 第六场 光头强的强迫症(线段树)
    bzoj1577 [USACO09FEB] Fair Shuttle
  • 原文地址:https://www.cnblogs.com/LMCC1108/p/10834140.html
Copyright © 2011-2022 走看看