#1284 : 機會渺茫
描述
小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
因爲M和N的值很大所以如果統計約數時不能直接開數組標記,此時,用map映射是很好的方法,避免了數組超限的問題;
統計一個數的約數只需要sqrt一下;最後他說讓輸出兩個互質的數,那麼我們約分一下分子分母就好,直接gcd求分子分母的最大公約數;解決。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<map>
#define LL long long
using namespace std;
map<LL,int>f;
LL gcd(int a,int b){
if(b==0){
return a;
}
else
return gcd(b,a%b);
}
int main() {
LL n,m;
while(scanf("%lld%lld",&n,&m)!=EOF) {
f.clear();
LL a=0,b=0,c=0;
LL gcdnum;
for(int i=1; i<=sqrt(n); i++) {
if(n%i==0) {
f[i]=1;
a++;
if(n/i!=i) {
f[i/n]=1;
a++;
}
}
}
for(int i=1; i<=sqrt(m); i++) {
if(m%i==0) {
b++;
if(f[i])
c++;
if(m/i!=i) {
if(f[m/i])
c++;
b++;
}
}
}
gcdnum=gcd(a*b,c);
printf("%lld %lld\n",a*b/gcdnum,c/gcdnum);
}
return 0;
}