1. 程式人生 > >【洛谷P1029】最大公約數和最小公倍數問題

【洛谷P1029】最大公約數和最小公倍數問題

題目傳送門P1029

題目描述

輸入22個正整數x_0,y_0(2 \le x_0<100000,2 \le y_0<=1000000)x0​,y0​(2≤x0​<100000,2≤y0​<=1000000),求出滿足下列條件的P,QP,Q的個數

條件:

  1. P,QP,Q是正整數

  2. 要求P,QP,Q以x_0x0​為最大公約數,以y_0y0​為最小公倍數.

試求:滿足條件的所有可能的22個正整數的個數.

輸入輸出格式

輸入格式:

22個正整數x_0,y_0x0​,y0​

輸出格式:

11個數,表示求出滿足條件的P,QP,Q的個數

輸入輸出樣例

輸入樣例

3 60

輸出樣例

4

題解

這道題很基礎就是道水題

最大公約數是x,所以設這兩個數為x*k1 , x*k2 (其中k1,k2互質)。x * k1 * k2 = y ,所以 k1*k2 = y / x (如果y / x 除不盡意味著沒答案)然後只要窮舉k1 , k2 的值即可,(k1*k2 = y / x 是輪換式,不妨設 k1 < k2 , 然後從1 ~ floor(sqrt(y0 / x0))窮舉)如果k1,k2 互質 , 那就說明找到 2 組解了,將 sum += 2 。

AC程式碼

#include<bits/stdc++.h>
using namespace std;
int x, y, sum;
int gcd(int x, int y) {
	return x % y == 0 ? y : gcd(y, x % y);
}
int main() {
	cin >> x >> y;
	if (y % x != 0) {
		cout<<0<<endl;
	}
	int k = y / x;
	for (int i = 1 ; i <= floor(sqrt(k)) ; i++) {
		if (k % i == 0) {
			int a = i, b = k / i;
			if (gcd(b, a) == 1) {
				sum += 2;
			}
		}
	}
	cout << sum << endl;
	return 0;
}

然而這種程式碼有個缺點,當資料給得很大的時候會超時。本人推薦下面這種思路。

我們都知道兩個數的最大公約數和最小公倍數的乘積就是這兩個數的乘積,那麼我們可以先把他們乘起來然後再遍歷它的因子。

程式碼如下:

#include<iostream>
#include<cmath>
using namespace std;
int m, n, ans;
int gcd(int x, int y) {
	if(y == 0)    {
		return x;
	}
	return gcd(y, x % y);
}
int main() {
	cin >> n >> m;
	for(int i = 1; i <= sqrt(m * n); i++) {
		if((m * n) % i == 0 && gcd(i,(m * n) / i) == n)
		ans++;
	}
	cout << ans * 2;
	return 0;
}

注:本段程式碼參考洛谷題解完成,有刪改