题目描述
输入 2 个正整数 x0,y0 (2≤x0<100000,2≤y0<=1000000),求出满足下列条件的P,Q的个数
条件:
- P,Q 是正整数
- 要求P,Q 以x0 为最大公约数,以y0为最小公倍数
试求:满足条件的所有可能的 2 个正整数的个数
输入格式:
2 个正整数x0,y0
输出格式:
1 个数,表示求出满足条件的 P,Q 的个数
输入样例 输出样例
3 60 4
说明
1、3,60
2、15,12
3、12,15
4、60,3
初学数论,兴奋不已……
解析:
因为:x_0 为P,Q 的最大公约数
所以:P = x_0*k1 Q=x_0*k2 (k1,k2 互质)
因为:y_0 为P,Q 的最小公倍数
所以:k1*k2*x_0=y_0 ==》 y0 / x0 = k1 * k2
因此我们只用枚举 k1 ,求出 k2 ,再判断 k1 , k2 是否互质 ,就可以啦
我们枚举的范围肯定不能超过y0,从样例可以看出,从 sk 开方的位置分为的两半,左右是 对称的,所以我们只需要求出左边一半,乘 2 就好啦
一个易懂代码
#include<stdio.h> #include<math.h> int gcd(int x,int y) { if(y==0) return x; else return gcd(y,x%y); } int main() { int x_0,y_0; scanf("%d%d",&x_0,&y_0); if(y_0%x_0!=0) { printf("0"); return 0; } int ans=0; int sk=y_0/x_0; for(int i=1;i<=sqrt(sk);++i) { if(sk%i==0) { int k1=i,k2=sk/i; if(gcd(k1,k2)==1) { ans+=2; } } } printf("%d",ans); return 0; }
一个浓缩代码(我都看不懂QWQ)
#include<stdio.h> #include<math.h> using namespace std; int gcd(int x,int y)// x:被除数 y:除数 { if(y==0) return x; return gcd(y,x%y);// gcd(除数,余数) } int main() { int n,m,ans=0; scanf("%d%d",&n,&m); for(int i=1;i<=sqrt(m*n);++i) { if((m*n)%i==0 && gcd((m*n)/i,i)==n) ans++; } printf("%d",ans*2); return 0; }