【洛谷】P1072 Hankson的趣味题

洛谷P1072 Hankson的趣味题

这个问题是这样的:已知正整数 a 0 , a 1 , b 0 , b 1 a_0,a_1,b_0,b_1 a0,a1,b0,b1设某未知正整数 x x x 满足:

x x x x 0 x_0 x0的最大公约数是 a 1 a_1 a1 x x x b 0 b_0 b0 的最小公倍数是 b 1 b_1 b1

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

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

输出格式
共 n 行。每组输入数据的输出结果占一行,为一个整数。

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

输入输出样例:
输入#1:

2 
41 1 96 288 
95 1 37 1776 

输出#1:

6 
2

数据范围:

  • 1 ≤ a 0 , a 1 , b 0 , b 1 ≤ 2 × 1 0 9 1\leq a_0,a_1,b_0,b_1\leq 2\times 10^9 1a0,a1,b0,b12×109 n ≤ 2000 n\leq 2000 n2000.

题目的大意也很简单,就是要找这样的x。由于a和b都在整个int范围内,所以试图找到一个限制x的条件。在最大公约数和最小公倍数问题里,其实直接寻找整除关系就可以了:
g c d ( x , a 0 ) = a 1 ⇒ a 1 ∣ x gcd(x,a_0)=a_1\quad \Rightarrow \quad a_1 | x gcd(x,a0)=a1a1x
l c m ( x , b 0 ) = b 1 ⇒ x ∣ b 1 lcm(x,b_0)=b_1\quad \Rightarrow \quad x | b_1 lcm(x,b0)=b1xb1
所以思路就出来了。穷举b_1的因数,这个因数范围在 I N T _ M A X \sqrt{INT\_ MAX} INT_MAX 内,穷举一个因数x的时候同时判断 b 1 x \frac{b_1}{x} xb1,就可以全部穷举一遍了。。还是要注意几个问题:

  • x要用long,否则x*b0之类的会溢出
  • x和y都要一起判断下
  • 输出之前用的cout,居然1.02sT了。。。改成printf就好了
#include <bits/stdc++.h>
using namespace std;
int t;
int a0,a1,b0,b1;
int gcd(int a,int b){
    return b==0?a:gcd(b,a%b);
}
int main(){
    cin>>t;
    while(t--){
        scanf("%d %d %d %d",&a0,&a1,&b0,&b1);
        int res=0;
        for(long x=1;x*x<=b1;x++){
            if(b1%x==0){
                if(x%a1==0&&gcd(x,a0)==a1&&x*b0/gcd(x,b0)==b1) res++;
                long y=b1/x;
                if(x!=y){
                    if(y%a1==0&&gcd(y,a0)==a1&&y*b0/gcd(y,b0)==b1) res++;
                }
            }
        }
        printf("%d\n",res);
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值