Detailed explanation of Luogu Qianqiu | P1029 [NOIP2001 Popularization Group] The problem of greatest common divisor and least common multiple [C++ language]

Blogger homepage: Yu·Xiansheng

Column address: Detailed Explanation of Thousand Questions in Luogu

Table of contents

Question description

Input format

Output format

Input and output samples

Analysis:

C++ source code:

C++ source code 2:

C++ source code 3:


-------------------------------------------------------------------------------------------------------------------------------- 

 --------------------------------------------------------------------------------------------------------------------------------

Question description

Input two positive integers x0​,y0​, and find the number of P and Q that meet the following conditions:

  1. P,Q are positive integers.

  2. It is required that P and Q take x0​ as their greatest common divisor and y0​ as their least common multiple.

Try to find: the number of all possible P and Q that satisfy the conditions.

 --------------------------------------------------------------------------------------------------------------------------------

Input format

There are two positive integers x0​,y0​ in a row.

 --------------------------------------------------------------------------------------------------------------------------------

Output format

One number per line means finding the number of P and Q that meet the conditions.

 --------------------------------------------------------------------------------------------------------------------------------

Input and output samples

Enter #1 to copy

3 60

Output #1 Copy

4

 --------------------------------------------------------------------------------------------------------------------------------

Analysis:

update on 2020/06/12: Fixed some unclear and ambiguous explanations.
update on 2022/07/21: Latex added.

prerequisite knowledge

  • How to find the greatest common divisor (i.e. \gcdgcd) and the least common multiple (i.e. \operatorname{lcm}lcm).

The key point of this question is that the product of two numbers is equal to the product of their greatest common divisor and their least common multiple . The formula is expressed as a\times b=\gcd(a,b) \times \operatorname{lcm}(a,b)a×b=gcd(a,b)×lcm(a,b). Let the two numbers as the answer be xx and yy, we need to make them meet the following three conditions at the same time, and count the number of such xx and yy (see the title description for the meaning of P, QP, Q):

  • x \times y=P \times Qx×y=P×Q
  • \gcd(x,y)=Pgcd(x,y)=P
  • \operatorname{lcm}(x,y)=Qlcm(x,y)=Q

We can enumerate xx and determine whether there is an integer yy that satisfies condition 11 (that is, whether xx is divisible by the product of P, QP, Q). After the first condition is met, then judge whether the current x, yx, and y can meet the other two conditions at the same time. Obviously, this approach will time out.

Consider optimizing this program. We actually don't need to enumerate twice, because for different x, yx, y, exchanging their values ​​can definitely get another set of corresponding solutions. Therefore, enumerate from 11 to \sqrt{P\times Q}P×Q​, and add 22 to the ansans value for each set of answers found.

There is a condition when a set of x, yx, y has corresponding solutions: the values ​​of x, yx, y are different. If they are the same, another set of numbers corresponding to them cannot be obtained after swapping. When x=yx=y, it is easy to get x=y=\gcd(x,y)=\operatorname{lcm}(x,y)x=y=gcd(x,y)=lcm(x,y). Therefore, a special judgment must be made on this. If P, QP, and Q are equal, this situation exists, and 11 must be subtracted from ansans.

Some code implementation tips:

  • There is a built-in function called \gcdgcd in c++  __gcd . upd: NOIP is now available.

  • When the products are the same and \gcdgcd are the same, \operatorname{lcm}lcm must also be the same, so you only need to judge whether the first and second conditions are met.

  -------------------------------------------------------------------------------------------------------------------------------

C++ source code:

#include<iostream>
using namespace std;
int ans=0;//ans是情况数量。 
int d(int a,int b){//求最大公约数函数。a,b是两个待求最大公约数的数,不是题里的x0y0。 
	if(a<b) swap(a,b);//确保a>b,为下一步除法做准备
	if(a%b==0) return b;//如果a/b余0,那么b就是最大公约数。比如10和5, 10/5余0,5就是最大公约数 
	else return d(b,a%b);//辗转相除法求最大公因数(其实交换ab那一步没必要,小除以大余小本身,到这里自然就换过来了,比如3和15,3/15余3,到这里就变成了15和3,嗯) 
}
int x(int a,int b){//最小公倍数 
	return (a*b/d(a,b));//最大公因数和最小公倍数的乘积等于原两个数的乘积。所以这两个数的乘积除以最大公因数等于最小公倍数。 
}
int main(){
	int x0,y0;//这才是x0y0. 
	cin>>x0>>y0;//(这里用个搜索就行了) 
	for(int i=x0;i<=y0;i++){//a一定在它的最大公因数和最小公倍数之间,这很明显 
		int j=x0*y0/i;//最大公因数和最小公倍数的乘积等于原两个数的乘积。老道理 。b就这样算 
		if(d(i,j)==x0&&x(i,j)==y0)// 如果ab(ij)的最大公因数,最小公倍数符合x0y0 
			ans++;//计数 
	}
	cout<<ans<<endl;
	return 0;
}	

  -------------------------------------------------------------------------------------------------------------------------------

C++ source code 2:

#include <bits/stdc++.h>
using namespace std;
long long x,y;
inline long long gcd(long long x,long long y)
{
	if(y==0) return x;
	return gcd(y,x%y);
}
int main()
{
	cin>>x>>y;
	long long ans=0;
	for(long long i=1;i<=sqrt(x*y);i++)
	{
		if(x*y%i==0&&gcd(i,x*y/i)==x) ans++;
	}
	ans*=2;
  	if(x==y) ans--;
   	cout<<ans;
	return 0;
}

  -------------------------------------------------------------------------------------------------------------------------------

C++ source code 3:

#include <iostream>
int main()
{
    int x, y;
    std::cin >> x >> y;
    if (y % x != 0)
        std::cout << 0;
    else
    {
        int quotient = y / x;
        int count = 0;        //统计素因数的个数
        int currentFactor = 2; //用来试验整除性的因数
        while (quotient > 1) //等于1时标志着分解完毕
        {
            if (quotient % currentFactor == 0)
            {
                count++;
                while (quotient % currentFactor == 0)
                    quotient /= currentFactor;//若能整除就除到底
            }
            currentFactor++;
        }
        std::cout << (1 << count);//使用位运算来产生2的方幂
    }
    return 0;
}

Guess you like

Origin blog.csdn.net/djfihhfs/article/details/128454881