1266: gcd和lcm(Java)

WUSTOJ 1266: gcd和lcm

参考

1naive1的博客

Description

  已知a,b的最大公约数为x,也即gcd(a,b)=x; a,b的最小公倍数为y,也即lcm(a,b)=y.给出x,y.求满足要求的a和b一共有多少种。

Input

  多组测试样例。每组给两个整数x,y.(1<=x<=100000,1<=y<=1000000000).

Output

  对于每个测试样例,输出一个整数,表示满足要求的(a,b)的种数。

Sample Input

3 60
2 2

Sample Output

4
1

HINT

  题目数据范围做了少许改动。

分析

  1. 当最大公约数(x)和最小公倍数(y)相同时,ab的取值只能有一种情况,即a = b = x = y
  2. 如果存在ab,则a * b * x = y,那么y % x = 0,因此如果余数不为0,那么种数为0
  3. 如果存在ab,那么x * z = ya * b = z,因此,只需要将a1循环到z的开方数即可。
  4. 对于ab还要满足互质才有效,如果不互质,那么最大公约数就不是x了,判断互质用辗转相除即可。
  5. 由于ab的值可以互换,因此每组满足条件的互质数,种数都要加2

代码

/**
 * 用时:284ms
 * @author PengHao
 * @version A1.1
 * @date 2019年4月17日 上午11:21:53
 */
import java.util.Scanner;

public class Main {

	private Scanner sc;
	private int x, y; // 最大公约数和最小公倍数

	public Main() {
		sc = new Scanner(System.in);
		while (sc.hasNext()) {
			x = sc.nextInt();
			y = sc.nextInt();
			System.out.println(count());
		}
		sc.close();
	}

	/**
	 * @return 种数
	 */
	private int count() {
		// 最大公约数和最小公倍数相等
		if (x == y) {
			return 1;
		}
		// 最小公倍数与最大公约数不是倍数关系
		if (0 != y % x) {
			return 0;
		}
		int z = y / x;
		int j, num;
		num = 0; // 初始0种
		// 小于等于开方数即可
		for (int i = 1; i * i <= z; i++) {
			j = z / i;
			// 倍数关系才能计算
			if (0 == z % i) {
				// 判断i,j是否互质,互质的话加2,a,b可互换
				if (coPrime(i, j)) {
					num += 2;
				}
			}
		}
		return num; // 返回种数
	}

	/**
	 * 辗转相除法,来自百度百科
	 * 
	 * @param a 一个数
	 * @param b 另一个数
	 * @return true 如果a和b互质
	 */
	private boolean coPrime(int a, int b) {
		while (true) {
			a = a % b;
			if (0 == a) {
				return 1 == b ? true : false;
			}
			b = b % a;
			if (0 == b) {
				return 1 == a ? true : false;
			}
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		new Main();
	}
}
原文地址:https://www.cnblogs.com/wowpH/p/11060821.html