题目描述:
已知正整数a0,a1,b0,b1,设某未知正整数x满足:
1、 x和a0的最大公约数是a1;
2、 x和b0的最小公倍数是b1。
Hankson的“逆问题”就是求出满足条件的正整数x的个数。
题解:
首先这里感谢xyw师哥的现场指导!(没有师哥csdn就不@了)
关于这个题目其实就是一个推导转换的过程:
gcd(x,a0) = a1 ---> gcd(x/a1,a0/a1) = 1
lcm(x,b0) = b1 ---> gcd(b1/x,b0/b1) = 1
我们同时发现x/a1
是b1/a1
的约数,同时我们知道约数总是成对出现的,所以另一个约数就是b1/x
。
那么这个题目就转换成了求解同时满足gcd(x/a1,a0/a1) = 1
和gcd(b1/x,b0/b1) = 1
的关于b1/a1
的约数。
那么就可以做了
AC代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int gcd(int a,int b)
{
return b ? gcd(b,a % b) : a;
}
int pd(int x,int y)
{
if(gcd(x,y) == 1) return 1;
else return 0;
}
int main()
{
int t;
cin >> t;
while(t--){
int a0,a1,b0,b1;
cin >> a0 >> a1 >> b0 >> b1;
if(b1 % a1 != 0) {
cout << '0' << endl;
continue;
}
int k = b1/a1,ans = 0;
for(int i = 1;i * i <= k;i++){
if(k % i == 0){
if(pd(i,a0/a1) && pd(k/i,b1/b0)) ans++;
if(i * i != k && pd(k/i,a0/a1) && pd(i,b1/b0)) ans++; //注意这里要判断一下sqrt(k) = i * i的情况因为这个时候的约数其实就只有一个
}
}
cout << ans << endl;
}
return 0;
}