Hankson 的趣味题

Posted wzq--boke

tags:

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

Hanks 博士是BT(Bio-Tech,生物技术)领域的知名专家,他的儿子名叫Hankson。现在,刚刚放学回家的Hankson 正在思考一个有趣的问题。

今天在课堂上,老师讲解了如何求两个正整数 c1 和 c2 的最大公约数和最小公倍数。现在Hankson 认为自己已经熟练地掌握了这些知识,他开始思考一个”求公约数”和“求公倍数”之类问题的“逆问题”,这个问题是这样的:已知正整数 a0,a1,b0,b1,设某未知正整数 x 满足:

1.x和 a0 的最大公约数是 a1;
2.x和 b0 的最小公倍数是 b1。
Hankson的“逆问题”就是求出满足条件的正整数 x 。但稍加思索之后,他发现这样的 x并不唯一,甚至可能不存在。因此他转而开始考虑如何求解满足条件的 x 的个数。请你帮助他编程求解这个问题。

 

首先把条件转化成数学式子

a1=gcd(x,a0);

b1=lcm(x,b0);

显然你会发现gcd比lcm好求,所以我们把第二个式子转化一下

首先你要知道个定理a*b=gcd(a,b)*lcm(a,b);

所以第二个式子转化过程

x*b0=lcm(x,b0)*gcd(x,b0);

x*b0=b1*gcd(x,b0);

x=b1/b0*gcd(x,b0);

 

整理一下

a1=gcd(x,a0);

x=b1/b0*gcd(x,b0);

首先可以很暴力想到枚举x进行判断,这样只能拿50分所以我们要优化一下

因为gcd(x,b0)<=b0 而gcd(x,b0)为b0约数,所以我们枚举gcd(x,b0),且gcd(x,b0)<=sqrt(b0);

令i=gcd(x,b0) 1<=i<=sqrt(b0);

判断x=b1/b0*i 和x=b1/b0*(b0/i)是否满足条件

还要有些特判,具体看代码

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define ll long long
using namespace std;
const int maxn=1000000+10101;
inline int read(){
    int x=0,f=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar())if(ch==-)f=-1;
    for(;isdigit(ch);ch=getchar())x=(x<<3)+(x<<1)+ch-0;
    return x*f;
}
int n,a0,a1,b0,b1;

int gcd(int x,int y){
    if(x<y)swap(x,y);
    if(y==0)return x;
    return gcd(y,x%y);    
}

int main(){
    n=read();
    for(int i=1;i<=n;i++){
        int ans=0;
        a0=read();a1=read();b0=read();b1=read();
        int kk=sqrt(b0);
        for(int i=1;i<=kk;i++){
            if(b0%i!=0)continue;  //注意1 
            int x1=b1/b0*i;
            if(gcd(x1,a0)==a1 && gcd(x1,b0)==i)ans++;
            if(b0/i==i)continue;//注意2 
            x1=b1/b0*(b0/i);
            if(gcd(x1,a0)==a1 && gcd(x1,b0)==b0/i)ans++;
        }
        printf("%d
",ans);
    }
    return 0;
}

 



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

Hankson 的趣味题

[NOIp 2009]Hankson的趣味题

Noip2009 Hankson的趣味题

P1072 Hankson 的趣味题

luogu1072Hankson 的趣味题 [数学]

NOIp2009 Hankson 的趣味题