P1072 Hankson的趣味题

Posted lsworld

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1072 Hankson的趣味题相关的知识,希望对你有一定的参考价值。

拿到本题的第一想法就是暴力枚举,这种方法肯定是可做的。具体能那多少分的话...就看数据心情了。

#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;
}

以上是关于P1072 Hankson的趣味题的主要内容,如果未能解决你的问题,请参考以下文章

luogu P1072 Hankson 的趣味题

luogu P1072 Hankson的趣味题

P1072 Hankson 的趣味题

P1072 Hankson的趣味题

Luogu P1072 NOIP2009 Hankson的趣味题暴力

luogu P1072 Hankson 的趣味题