2017年8月12日提高组T2 YMW的数学题

53 篇文章 0 订阅
23 篇文章 0 订阅

Description


YMW最近迷上了数学,听BPM说,善于思考的孩纸才是好孩纸呢,于是他一边看书,一边开始思考些问题。他看到书上说枚举是最强大的算法,他很不服气,思考片刻,便想出一道题,如果我们有两个正整数a,b,那会有多少对数,满足他们之间的最大公因数是a,最小公倍数是b呢?而你是暴力的最忠实粉丝,你能用枚举进行解决吗?

Input


多组数据,每组数据只有一行,每行两个正整数a,b
以输入文件结束结尾

Output


每组数据输出一个整数,表示符合的有多少对,每组数据占一行

Hint


样例解释,第一组存在4对(3,60),(12,15),(15,12),(60,3),第二组只有(2,2)
数据范围:
不超过100组数据
对于30%的数据2<=a<=2000,2<=b<=2000
对于70%的数据2<=a<=20 0000,2<=b<=20 0000
对于100%的数据2<=a<=20 0000 0000,2<=b<=20 0000 0000

Source


BY BPM

Solution


水题

已知a*b/gcd(a,b)=lcm(a,b),变形得lcm(a,b)*gcd(a,b)=a*b
对于给定的每个gcd和lcm,我们求积并枚举其中一个a,找另一个b

显然这样做还是会T的。不难发现a=gcd(a,b)*k,b=gcd(a,b)*l这样a、b均为gcd的倍数,那么我们枚举gcd前的倍数就可以了

Code


#include <stdio.h>
#include <math.h>
#define rep(i, st, ed) for (int i = st; i <= ed; i += 1)
#define max(x, y) (x)>(y)?(x):(y)
#define ll long long
inline int gcd(int x, int y){return !y?x:gcd(y,x % y);}
int main(void){
    int n, m;
    while (scanf("%d %d", &n, &m) != EOF){
        if (n == m){
            puts("1");
            continue;
        }
        ll lim =(ll)(n) * (ll)(m);
        int ans = 0;
        rep(i, 1, sqrt(lim) / n){
            int x = n * i;
            int y = lim / x;
            ans += (!(lim % x) && gcd(x, y) == n);
        }
        printf("%d\n", ans * 2);
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值