【hihocoder】機會渺茫(map,離散化,概率計算,gcd)

#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

因爲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;
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章