zoukankan      html  css  js  c++  java
  • 洛谷 UVA11388 GCD LCM

    UVA11388 GCD LCM

    Description of the title

    PDF

    The GCD of two positive integers is the largest integer that divides both the integers without any remainder.

    The LCM of two positive integers is the smallest positive integer that is divisible by both the integers.

    A positive integer can be the GCD of many pairs of numbers.

    Similarly, it can be the LCM of many pairs of numbers.

    In this problem, you will be given two positive integers.

    You have to output a pair of numbers whose GCD is the first number and LCM is the second number.

    Input

    The first line of input will consist of a positive integer T.

    T denotes the number of cases.

    Each of the next T lines will contain two positive integer, G and L.

    Output

    For each case of input, there will be one line of output.

    It will contain two positive integers a and b, a ≤ b, which has a GCD of G and LCM of L.

    In case there is more than one pair satisfying the condition, output the pair for which a is minimized.

    In case there is no such pair, output ‘-1’.

    Constraints

    • T ≤ 100

    • Both G and L will be less than 231 .

    Sample Input

    2 1 2 3 4

    Sample Output

    1 2 -1

    Solution

    This is a Chinese puzzle!

    请记住,看到gcd/lcm,先想数论,而不是暴力!

    想不出来再打表找规律!

    普及- 的题,不是模拟就是数论。       ——佚名(我)

    Algorithm(Naive)

    暴力代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 inline unsigned long long gcd(unsigned long long a,unsigned long long b)
     4 {
     5     if(b==0) return a;
     6     if(b==1) return 1;
     7     if(a%2==0&&b%2==0) return 2*gcd(a/2,b/2);
     8     if(a%2==1&&b%2==0) return gcd(a,b/2);
     9     if(a%2==0&&b%2==1) return gcd(a/2,b);
    10     if(a%2==1&&b%2==1) return gcd(b,a%b);
    11 //    return (b==0)?a:gcd(b,a%b);
    12 }
    13 unsigned long long t,a,b,j,g,l,flag;
    14 int main()
    15 {
    16     cin>>t;
    17     while(t--)
    18     {
    19         cin>>g>>l;
    20         j=g*l;
    21         flag=1;
    22         for(int a=1;a*a<=j;a++)
    23         {
    24             if(j%a==0)
    25             if(gcd(a,j/a)==g){
    26                 cout<<a<<" "<<j/a<<endl;
    27                 flag=0;
    28                 break;
    29             }
    30         }
    31         if(flag) cout<<"-1
    ";
    32     }
    33 
    34     return 0;
    35 }
    朴素算法Code

    时间复杂度

    O(t sigma log(sqrt(1 to g*j)))

    understand

    没脑子的我都懂怎么暴力了……

    i*j==g*l

    Algorithm(Arithmetical)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 unsigned long long t,g,l;
     4 int main()
     5 {
     6     cin>>t;
     7     while(t--)
     8     {
     9         cin>>g>>l;
    10         if(l%g==0)
    11             cout<<g<<" "<<l<<endl;
    12         else
    13             cout<<"-1
    ";
    14     }
    15     return 0;
    16 }

    时间复杂度

    O(t)

    Understand

    这个要一点脑子哈

    首先,若有两个数i,j

    且g=gcd(i,j),l=lcm(i,j);

    那么,

    l | g

    即g整除l

    证明:

    从文字的角度理解

    lcm,两数最小的公倍数,那么l一定是i,j的倍数

    gcd,两数最大的公因数,那么g一定是i,j的因数

    那么l有因数i,j

    当然也有因数g!

    证毕

    所以l%g==0

    否则,直接输出-1

    但是如何确定:(g,l)就是i最小,j最大的一组解呢?

    设n=i/g

    由g是i,j的gcd

    所以g是i的因子

    即i是g的倍数

    那么定有n为正整数

    那么n的最小值为1

    此时i==gcd(i,j)

    又因为i不能比g小

    故i的最小值即为g

    此时的g,imin,j已确定

    根据公式i*j=gcd(i,j)*lcm(i,j)

    jmax即可确定

    证毕

    又水了一篇题解鸭

  • 相关阅读:
    Computer Vision: Algorithms and ApplicationsのImage processing
    LOJ6079「2017 山东一轮集训 Day7」养猫
    网络七层协议及其作用
    观察者模式深度剖析
    NIO 中的读和写
    NIO的通道和缓冲区
    NIO简介
    使用OutputStream向屏幕上输出内容
    对象的序列化
    PushBackInputStream回退流
  • 原文地址:https://www.cnblogs.com/send-off-a-friend/p/11332835.html
Copyright © 2011-2022 走看看