http://www.cnblogs.com/allh123/archive/2013/08/24/3279747.html
参考上述两篇文章
GCD and LCM
Problem Description
Given two positive integers G and L, could you tell me how many solutions of (x, y, z) there are, satisfying that gcd(x, y, z) = G and lcm(x, y, z) = L?
Note, gcd(x, y, z) means the greatest common divisor of x, y and z, while lcm(x, y, z) means the least common multiple of x, y and z.
Note 2, (1, 2, 3) and (1, 3, 2) are two different solutions.
Note, gcd(x, y, z) means the greatest common divisor of x, y and z, while lcm(x, y, z) means the least common multiple of x, y and z.
Note 2, (1, 2, 3) and (1, 3, 2) are two different solutions.
Input
First line comes an integer T (T <= 12), telling the number of test cases.
The next T lines, each contains two positive 32-bit signed integers, G and L.
It’s guaranteed that each answer will fit in a 32-bit signed integer.
The next T lines, each contains two positive 32-bit signed integers, G and L.
It’s guaranteed that each answer will fit in a 32-bit signed integer.
Output
For each test case, print one line with the number of solutions satisfying the conditions above.
Sample Input
2 6 72 7 33
Sample Output
72 0解题思路:将满足条件的一组x,z,y都除以G,得到x‘,y',z',满足条件gcd(x',y',x') = 1,同时lcm(x',y',x') = G/L.
特判,当G%L != 0 时,无解。
然后素数分解G/L,假设G/L = p1^t1 * p2^t2 *````* pn^tn。
满足上面条件的x,y,z一定为这样的形式。
x' = p1^i1 * p2^i2 *```* pn^in.
y' = p1^j1 * p2^j2 * ```*pn^jn.
z' = p1^k1 * p2^k2 * ```*pn^kn.
为了满足上面的条件,对于p1,一定有max(i1,j1,k1) = t1.min(i1,j1,k1) =0;则当选定第一个数为0,第二个数为t1时,第三个数可以为0-t1,又由于有顺序的,只有
(0,t1,t1) 和(0,t1,0)这两种情形根据顺序只能产生四种结果,其他的由于三个数都不一样,一定能产生6种,所以最后产生了6*(t1-1)+3*2 = 6*t1种,根据乘法原理以及关于素数分解的唯一性,反过来,素数组合必然也是唯一的数,一共有6*t1 * 6*t2 *`````*6*tn种选法。
(上述计算的理解:第一个为0 第二个t1 第三个为0~t1中的一个,三个位置可以相互交换,但是由于当第三个0或者t1的时候,交换位置会有重复,所以没有冲突的情况是6*(t1 - 1),加上 第三个为0是三种情况 第三个是t1的时候是三种情况,所以总共是6*t1种情况)#include <iostream> #include <map> using namespace std; int findMin(int x) { for(int i = 2;i <= x;i ++) { if(x%i == 0) { return i; } } return -1; } int main() { int T; cin >> T; while(T --) { int G,L; cin >> G >> L; if(L%G != 0) { cout << 0 << endl; } else { int number = L/G; map<int,int> primeCount; int t; while(number != 1) { t = findMin(number); if(t == -1) { break; } primeCount[t] ++; number /= t; } map<int,int>::iterator it; int result = 1; for(it = primeCount.begin();it != primeCount.end();it ++) { result *= 6 * it->second; } cout << result<<endl; } } return 0; }