{ }codelper
最大公约数定义函数溢出P0037

最大公约数与最小公倍数

一行给出两个用空格分隔的正整数 a、b。
在一行中输出 a 与 b 的最大公约数和最小公倍数,用一个空格分隔。

输入
1 ≤ a, b ≤ 10^12。
最小公倍数不超过 10^15。
输出
最大公约数 最小公倍数
样例 1 · stdin
12 18
stdout
6 36
样例 2 · stdin
987000000000 977000000000
stdout
1000000000 964299000000000
main.py
输入(stdin)

运行时这些行会依次作为 input()/标准输入传入(运行中不会等待输入)。

$ 就绪

请在电脑上打开以编写和运行代码。在手机上可以查看题目和题解。

其他语言怎么写?查看各语言题解 · 8 种语言题解

最大公约数用辗转相除法(a, b = b, a % b 直到 b 为 0),最小公倍数要像 a / g * b 这样先除后乘。
若写成 a * b / g 先乘,示例 2 中 a*b ≈ 9.6×10^23,会让 C、C++、Java、C# 的 64 位 long(约 9.2×10^18)溢出,也会让 JavaScript、TypeScript、Craykon 超过 2^53 而末位出错。
只有整数无上限的 Python 两种写法都对。
10^12 放不进 32 位 int(约 21 亿),所以 C 系语言一开始就用 long/long long 读入。
现成函数:Python math.gcd,C++ std::gcd(<numeric>),C# BigInteger.GreatestCommonDivisor。
Craykon 用 最大公约数(a, b) { … 返回 a; } 定义函数;因为 / 会除出小数,商用 数学.商(a, g) 求。

Pythonmain.py · 9 行
def gcd(a, b):    while b:        a, b = b, a % b    return a  a, b = map(int, input().split())g = gcd(a, b)print(g, a // g * b)
JavaScriptmain.js · 9 行
const [a, b] = require("fs").readFileSync(0, "utf8").trim().split(/\s+/).map(Number); function gcd(a, b) {  while (b !== 0) [a, b] = [b, a % b];  return a;} const g = gcd(a, b);console.log(`${g} ${(a / g) * b}`);
TypeScriptmain.ts · 10 行
import { readFileSync } from "node:fs";const [a, b]: number[] = readFileSync(0, "utf8").trim().split(/\s+/).map(Number); function gcd(a: number, b: number): number {  while (b !== 0) [a, b] = [b, a % b];  return a;} const g = gcd(a, b);console.log(`${g} ${(a / g) * b}`);
JavaMain.java · 19 行
import java.util.Scanner; public class Main {    static long gcd(long a, long b) {        while (b != 0) {            long t = a % b;            a = b;            b = t;        }        return a;    }     public static void main(String[] args) {        Scanner sc = new Scanner(System.in);        long a = sc.nextLong(), b = sc.nextLong();        long g = gcd(a, b);        System.out.println(g + " " + (a / g * b));    }}
C#Main.cs · 20 行
using System; class Program{    static long Gcd(long a, long b)    {        while (b != 0)        {            (a, b) = (b, a % b);        }        return a;    }     static void Main()    {        long[] v = Array.ConvertAll(Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries), long.Parse);        long g = Gcd(v[0], v[1]);        Console.WriteLine($"{g} {v[0] / g * v[1]}");    }}
C++main.cpp · 9 行
#include <iostream>#include <numeric> int main() {    long long a, b;    std::cin >> a >> b;    long long g = std::gcd(a, b);    std::cout << g << ' ' << a / g * b << '\n';}
Cmain.c · 18 行
#include <stdio.h> long long gcd(long long a, long long b) {    while (b != 0) {        long long t = a % b;        a = b;        b = t;    }    return a;} int main(void) {    long long a, b;    scanf("%lld %lld", &a, &b);    long long g = gcd(a, b);    printf("%lld %lld\n", g, a / g * b);    return 0;}
Craykonmain.cray · 16 行
최대공약수(a, b){    当 (b != 0)    {        t = a % b;        a = b;        b = t;    }    返回 a;} 수들 = 控制台.读数字();a = 수들[0];b = 수들[1];g = 최대공약수(a, b);控制台.输出(g + " " + 数学.商(a, g) * b);