拿到本题的第一想法就是暴力枚举,这种方法肯定是可做的。具体能那多少分的话...就看数据心情了。
#include<iostream>
#include<cstdio>
using namespace std;
int n,a,aa,b,bb,i,j,d,dd;
int gcd(int x,int y)
{
if(x%y==0)
return y;
return gcd(y,x%y);//求gcd
}
int main()
{
cin>>n;
for(i=1;i<=n;i++)
{
int ans=0;
cin>>a>>aa>>b>>bb;
for(j=aa;j<=bb;j++)
{
d=gcd(a,j);
dd=j/gcd(b,j)*b;//两项枚举
if(d==aa && dd==bb)
ans++;//如果都符合,那么ans++;
}
cout<<ans<<endl;
}
return 0;
}
用这种暴力的方法在本题可以得50分,挺多的了。
那么如果想得满分,肯定要以某种方式优化,本题如何优化呢?
把题目简化可以写成:
gcd(x,a0)=a1 lcm(x,b0)=b1
因为两个数gcd,lcm的关系:ab=gcd(a,b)lcm(a,b)
可以得出bx=bb * gcd(x,b)
x=bb/b * gcd(x,b)
我们令I=gcd(x,b) 那么I肯定在1到根号下b之间。
然后判断x是否等于bb/b* i是否满足条件。
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int gcd(int x,int y)
{
if(y==0) return x;
else return gcd(y,x%y);
}
int main()
{
int n,a,aa,b,bb,x;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a>>aa>>b>>bb;
int ans=0;
if(bb%b!=0)
{
cout<<"0"<<endl;
continue;
}
for(int j=1;j<sqrt(b);j++)
{
if(b%j==0)
{
x=bb/b*j;
if(gcd(x,b)==j&&gcd(x,a)==aa)
ans++;
x=bb/b*(b/j);
if(gcd(x,b)==b/j&&gcd(x,a)==aa)
ans++;
}
}
int k=int(sqrt(b));
if(k*k==b && b%k==0)
{
x=bb/b*k;
if(gcd(x,b)==k && gcd(x,a)==aa)
ans++;
}
cout<<ans<<endl;
}
return 0;
}
耶