【Hankson 的趣味题】主要的数学公式推理
最大公约数
\(gcd(\) \(x\) \(,a_0)=a_1\)
等式的性质
\(gcd(\) \(x \over a_1\) \(,\) \(a_0 \over a_1\) \()=1\)
最小公倍数
\(lcm(x,b_0)=b_1\)
定义四个数 \(a,b,m,n\)
其中\(a,b\)是已经知道的两个数,\(m\)是最大公约数,\(n\)是最小公倍数
\(a=x*m;\)
\(b=y*m;\)
\(a*b=x*y*m*m\)
短除得最小公倍数 \(n=x*y*m\)
\(m*n=a*b=(x*y*m)*m\)
\(m=\) \(ab \over n\)
因为\(m\)是最小公约数
所以\(gcd(a,b)=m\)
那么\(gcd(a,b)=\) \(ab \over n\) \(=\) \(ab \over lcm(a,b)\)
然后将\(a,b\)替换成\(x,b_0\)
\(gcd(x,b_0)=\) \(xb_0 \over lcm(x,b_0)\)
因为\(lcm(x,b_0)=b_1\)
所以\(gcd(x,b_0)=\) \(xb_0 \over b_1\)
\(gcd(\) \(x \over \frac {xb_0}{b_1}\) \(,\) \(b_0 \over \frac {xb_0}{b_1}\) $)=gcd( $ \(xb_1 \over xb_0\) \(,\) \(b_0b_1 \over xb_0\) $ )=gcd($ \(b_1 \over b_0\) \(,\) \(b_1 \over x\) \()=1\)
(这个式子就是上面那个式子左右两边同时除以了\(xb_0 \over b_1\),然后进行了个约分)
上面我们推出了\(gcd(\) \(x \over a_1\) \(,\) \(a_0 \over a_1\) \()=1\)
然后写出\(gcd\)函数,把这两个式子代入代码即可
至于代码……枚举每一个数,一直枚举到那个数的平方根(防止重复枚举,降低复杂度)
#include<iostream>
#include<cmath>
using namespace std;
int gcd(int a,int b)
{
if(b==0) return a;
else return gcd(b,a%b);
}
int main()
{
int n;
cin>>n;
while(n--)
{
int a0,a1,b0,b1,ans=0;
cin>>a0>>a1>>b0>>b1;
for(int x=1;x<=sqrt(b1);x++)
{
if(b1%x==0)
{
if(x%a1==0&&gcd(x/a1,a0/a1)==1&&gcd(b1/b0,b1/x)==1) ans++;
int y=b1/x;
if(x==y) continue;
if(y%a1==0&&gcd(y/a1,a0/a1)==1&&gcd(b1/b0,b1/y)==1) ans++;
}
}
cout<<ans<<endl;
}
return 0;
}

浙公网安备 33010602011771号