#1284 : 机会渺茫
时间限制:5000ms
单点时限:1000ms
内存限制:256MB
描述
小Hi最近在追求一名学数学的女生小Z。小Z其实是想拒绝他的,但是找不到好的说辞,于是提出了这样的要求:对于给定的两个正整数N和M,小Hi随机选取一个N的约数N',小Z随机选取一个M的约数M',如果N'和M'相等,她就答应小Hi。
小Z让小Hi去编写这个随机程序,到时候她review过没有问题了就可以抽签了。但是小Hi写着写着,却越来越觉得机会渺茫。那么问题来了,小Hi能够追到小Z的几率是多少呢?
输入
每个输入文件仅包含单组测试数据。
每组测试数据的第一行为两个正整数N和M,意义如前文所述。
对于40%的数据,满足1<=N,M<=106
对于100%的数据,满足1<=N,M<=1012
输出
对于每组测试数据,输出两个互质的正整数A和B(以A分之B表示小Hi能够追到小Z的几率)。
- 样例输入
-
3 2
- 样例输出
-
4 1
提示:f[i]用来标记i为n的约数,m/i也为约数。然后遍历m约数的时候,如果f[i]存在,即i为n,m公共约数。最后需要求最大公约数,通分。
AC代码:1 #include "iostream" 2 #include "math.h" 3 #include "map" 4 #define MAX 1000000 5 6 using namespace std; 7 typedef long long LL; 8 9 LL n, m; 10 map<LL, int>f; 11 12 LL gcd(LL a, LL b) 13 { 14 if (b == 0) 15 return a; 16 else 17 return gcd(b, a%b); 18 } 19 20 21 int main() 22 { 23 cin >> n >> m; 24 LL p = 0, q = 0, r = 0 ; 25 LL gcdnum; 26 27 for (LL i = 1; i*i <= n; i++){ 28 if (n % i == 0) 29 { 30 f[i] = 1; 31 f[n / i] = 1; 32 p++; 33 if (i != n / i) 34 p ++; 35 } 36 } 37 38 for (LL i = 1; i*i <= m; i++){ 39 if (m % i == 0) 40 { 41 q++; 42 if (f[i]) 43 r++; 44 45 if (i != m / i) 46 { 47 q++; 48 if (f[m / i]) 49 r++; 50 } 51 } 52 } 53 54 gcdnum = gcd(p*q, r); 55 56 cout << p*q / gcdnum << " " << r / gcdnum; 57 58 }