【z12】&&【b092】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 的个数。请你帮
助他编程求解这个问题。
格式
输入格式

第一行为一个正整数 n,表示有 n 组输入数据。接下来的 n 行每
行一组输入数据,为四个正整数 a0,a1,b0,b1,每两个整数之间用一个空格隔开。输入
数据保证 a0能被 a1 整除,b1 能被 b0整除。
输出格式

共n 行。每组输入数据的输出结果占一行,为一个整数。
对于每组数据:若不存在这样的 x,请输出 0;
若存在这样的 x,请输出满足条件的 x 的个数;
样例1
样例输入1[复制]

2
41 1 96 288
95 1 37 1776
样例输出1[复制]

6
2
限制
每个测试点1s

【题目链接】:http://noi.qz5z.com/viewtask.asp?id=z12

【题解】

题目的要求是
gcd(x,a0)==a1;···①
lcm(x,b0)==b1;···②
则根据最大公约数gcd和lcm的关系->q*w/gcd(q,w) == lcm(q,w);
由①②可得
gcd(x,a0)==a1;
gcd(x,b0) == x*b0/b1
进一步两边同时除右边那个东西
gcd(x/a1,a0/a1)==1; ···③
gcd(b1/b0,b1/x)==1; ···④
而题目限制了a1能整除a0,b0能整除b1;
而a1<=b1(因为要求x和a0的最大公因数为a1则x>=a1,又x和b0的最小公倍数为a1,所以x<=b1->则a1<=b1);
所以只要枚举b1的因子x就好;(因为b1/x要为整数);
然后再看看a1能不能整除x(因为x/a1也要为整数);
最后再判断③和④是不是成立的;
写个gcd就好;
b1的因子的话只要i从1->sqrt(b1)枚举就好;
然后i是b1的因子的话b1/i也是b1的因子(对称的);
(要注意x*x的情况,不然会多算);
数的因子其实没想象的那么多(我记得1e8才100多个的样子);
所以最后虽然又乘了1000;
也只是相当于for (i= 1 ->8e7左右);
外层判断一下i是不是b1的因子;
但是(进入)for里面做的事情很少;(因子少);
复杂度也很可观吧.

【完整代码】

#include <cstdio>
#include <algorithm>
#include <cmath>

using namespace std;

int a0,a1,b0,b1,n;

int main()
{
   // freopen("F:\\rush.txt","r",stdin);
    scanf("%d",&n);
    for (int i = 1;i <= n;i++)
    {
        int num = 0;
        scanf("%d%d%d%d",&a0,&a1,&b0,&b1);
        int len = int(sqrt(double(b1)));
        for (int i = 1; i<= len;i++)
            if ((b1%i)==0)
            {
                int x = i;
                if ((x%a1)==0)
                    if (__gcd(x/a1,a0/a1)==1 && __gcd(b1/b0,b1/x)==1)
                        num++;
                x = b1 / x;
                if (x!= i && (x%a1)==0)
                    if (__gcd(x/a1,a0/a1)==1 && __gcd(b1/b0,b1/x)==1)
                        num++;
            }
        printf("%d\n",num);
    }
    return 0;
}
posted @ 2017-10-04 18:45  AWCXV  阅读(172)  评论(0编辑  收藏  举报