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整除。

输出描述:

对于每组数据:若不存在这样的x,请输出0;
若存在这样的x,请输出满足条件的x的个数;
示例1

输入

复制
2
41 1 96 288
95 1 37 1776

输出

复制
6
2

说明

第一组输入数据,x可以是9、18、36、72、144、288,共有6个。
第二组输入数据,x可以是48、1776,共有2个。

备注:

对于50%的数据,保证有1≤a0,b1,b0,b1≤10000且n≤100。
对于100%的数据,保证有1≤a0,b1,b0,b1≤2,000,000,000且n≤2000。

题解:

根据lcm的求解方式lcm(a,b)=a*b/gcd(a,b)可以得到 x|b1
于是我们可以枚举b1的约数,只需要特判一下x/b1=x的情况即可

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <string>
 5 #include <cstring>
 6 #include <cstdlib>
 7 #include <cmath>
 8 #include <stack>
 9 #include <queue>
10 #include <set>
11 #include <map>
12 #include <vector>
13 #include <ctime>
14 #include <cctype>
15 #include <bitset>
16 #include <utility>
17 #include <sstream>
18 #include <complex>
19 #include <iomanip>
20 #define inf 0x3f3f3f3f
21 typedef long long ll;
22 using namespace std;
23 int n,a0,a1,b0,b1;
24 // x 和a0 的最大公约数是a1   // x 和b0 的最小公倍数是b1
25 int gcd(int a,int b)
26 {
27     return a==0?b:gcd(b%a,a);
28 
29 }
30 int lcm(int a, int b)
31 {
32     return a / gcd(a, b) * b;
33 }
34 int main()
35 {
36     scanf("%d",&n);
37     while(n--)
38     {
39        scanf("%d%d%d%d",&a0,&a1,&b0,&b1);
40         int jg = 0 ;
41         for(int i = 1 ; i * i <= b1 ; i ++ )
42         {
43             jg=0;
44             for(int i = 1; i * i<= b1; i ++)
45             {
46                 if(b1 % i == 0)
47                 {
48                     if(lcm(b0, i) == b1 && gcd(a0, i) == a1)
49                         jg ++;
50                     int x = b1 / i;//特判一下
51                     if(x != i)
52                     {
53                         if(lcm(b0, x) == b1 && gcd(a0, x) == a1)
54                             jg ++;
55                     }
56                 }
57             }
58         }
59         printf("%d\n",jg);
60     }
61     return 0;
62 }

 

 

posted @ 2019-12-06 17:27  北陌晨  阅读(221)  评论(0)    收藏  举报