丑数三 C语言

long min(long a, long b) {
return a<b?a:b; }

 long LCM(long a,long b){
    
    long Multi = a * b;
    //求最小公倍数
    
    while(b > 0){
        long tmp = a % b;
        a = b;
        b = tmp;
    }

    return Multi/a;
}
 


int nthUglyNumber(int n, int a, int b, int c) {
    long ab = LCM(a, b);
    long ac = LCM(a, c);
    long bc = LCM(b, c);
    long abc = LCM(ab, c);
    long l = min(a, min(b, c));
    long r = n*l;
    while (l < r) {//这个才是点睛之笔  大佬厉害
        long m = l + (r - l) / 2;
        long count = m / a + m / b + m / c - m / ab - m / ac - m / bc + m / abc;//容斥定理,一个丑数肯定是由若干个基本丑数相乘而来,有的丑数只有n1个a得到
        if (count < n) {
            l = m + 1;
        } else {
            r = m;
        }
    }
    return l;
}

参考大佬的代码和讲解而成。这代码越想越着迷!
第一
采用容斥定理,判断一个数前面有多少个丑数
x = an1bn2c*n3+m; n1+n2+n3 = m;已知 a,b,c和x求m0

1.该数只能被a整除 (该数一定是a 的整数倍)

2.该数只能被b整除 (该数一定是b 的整数倍)

3.该数只能被c整除 (该数一定是c 的整数倍)

4.该数只能被a和b同时整除 (该数一定是a、b最小公倍数的整数倍)

5.该数只能被a和c同时整除 (该数一定是a、c最小公倍数的整数倍)

6.该数只能被b和c同时整除 (该数一定是b、c最小公倍数的整数倍)

7.该数只能被a和b和c同时整除(该数一定是a、b、c的最小公倍数的整数倍)

所以,我们只需要分别计算以上七项就能得到结果了!让我们分别来看(用MCM+下标表示最小公倍数):

情况1 = X/a - 情况4 - 情况5 - 情况7 情况2 = X/b - 情况4 - 情况6 - 情况7 情况3 = X/c -
情况5 - 情况6 - 情况7 情况4 = X/MCM_a_b - 情况7 情况5 = X/MCM_a_c - 情况7 情况6 =
X/MCM_b_c - 情况7 情况7 = X/MCM_a_b_c

作者:Alfeim
链接:https://leetcode-cn.com/problems/ugly-number-iii/solution/er-fen-fa-si-lu-pou-xi-by-alfeim/
来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处

第二
寄托于二分算法
第三
循环终止的条件,可以直接找到第n个丑数,而不是包含n个丑数的数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值