解法一、枚举法
[解题思路]
P,Q 以x0为最大公约数,通过碾转相除法求得到x0,y0为最小公倍数,通过P*Q/x0可以求得y0,根据最大公约数与最小公倍数的关系可以得到P*Q=x0*y0;
所以穷举Pi(i=1,...,y0),通过P,x0,y0,求出Q,判断是否符合条件。
[代码实现]
#include<stdio.h>
#include<iostream>
using namespace std;
int gcd(int a,int b) /*碾转相除法*/
{
return a%b?gcd(b,a%b):b;
}
int main()
{
int x,y,P,Q,ans=0;
scanf("%d %d",&x,&y);
for(P=x;P<=y;P++)
{
Q=y/(P/x);
if(P*Q/gcd(P,Q)==y && gcd(P,Q)==x) /* P*Q/x最小公倍数是否等于y, gcd(P,Q)最大公约数是否为x */
{
ans++;
}
}
printf("%d",ans);
return 0;
}
[解题思路]
因为x0为最大公约数,所以p,q中两数肯定是这个数的倍数,又因为y0要作为最小公倍数,因此y0的因子肯定包含x0(不包含的情况下不存在p,q)
因此将y0/x0后出来的解进行质因数分解后将相同的因子乘在一起,得到的就是p在x0的倍数的情况下可以乘上的积
举个例子:
当x0=3,y0=60时 , p,q两数中的所有因子的集合肯定等于y0中的因子的集合,因此y0/x0=20,20分解后即为2*2*5,如果不去重,p乘上2后会导致p,q都存在多余的公约数2,与题意不符,因此将分解后的因子集合去重并且将2全部乘起来,得到4,5,接下来p可能乘上的是4、5或者4*5,因此要将集合遍历
最后p,q可能是下面的
3*1=3 60/1=60
3*5=15 60/5=12
3*4=12 60/4=15
3*20=60 60/20=3
共两组互为质数,分别是1和20,4和5,4个解
[代码实现]
#include<iostream>
using namespace std;
int gcd(int a,int b)
{
if (a==0) return b;
gcd(b%a,a);
}
int main()
{
int x,y,ans=0; /* x,y分别为最大公约数和最小公倍数 */
cin>>x>>y;
if (y%x!=0) /* y不能整除x,这种情况是P、Q是不存在的 */
{
cout<<0;
return 0;
}
int t=y/x;
for (int P=1;P*P<=t;P++) /* P*P是为了防止重复并且提高效率 */
{
int Q=t/P;
if (t%P==0&&gcd(P,Q)==1) /* 首先x/y要能整除P 并且Q要与P互为质数 */
ans+=2; /* 找到一组就加2 */
}
cout<<ans;
}