当前位置 博文首页 > 文章内容

    丑数

    作者: 栏目:未分类 时间:2020-08-22 18:01:42

    本站于2023年9月4日。收到“大连君*****咨询有限公司”通知
    说我们IIS7站长博客,有一篇博文用了他们的图片。
    要求我们给他们一张图片6000元。要不然法院告我们

    为避免不必要的麻烦,IIS7站长博客,全站内容图片下架、并积极应诉
    博文内容全部不再显示,请需要相关资讯的站长朋友到必应搜索。谢谢!

    另祝:版权碰瓷诈骗团伙,早日弃暗投明。

    相关新闻:借版权之名、行诈骗之实,周某因犯诈骗罪被判处有期徒刑十一年六个月

    叹!百花齐放的时代,渐行渐远!



    一、题目

    我们把只包含因子2、3和5的数称作丑数(Ugly Number)。
    求按从小到大的顺序的第1500个丑数。例如6、8都是丑数,但14不是,因为它包含因子7。习惯上我们把1当做第一个丑数。

    二、问题分析

    假设这个数为 n, 如果n是丑数,只有三种可能:

    n是能整除2,即 n % 2 == 0,且 n/2 是丑数。
    n % 3 == 0 且 n/3是丑数。
    n % 5 == 0且 n / 5是丑数。
    三种可能只要满足其中一种,就可以确认是丑数了。即后面的丑数是由前一个丑数乘以2,3,5中的一个得来

    状态转移方程

    u(i) = min(u2(i-1)*2, u3(i-1)*3, u5(i-1)*5)  // u2、u3、u5代表2,3,5倍数的队列。
    

    详细代码

    /* 3个数中的最小值 */
    int Min(int number1, int number2, int number3)
    {
        int min = (number1 < number2) ? number1 : number2;
        min = (min < number3) ? min : number3;
    
        return min;
    }
    
    /* 创建数组保存已经找到的丑数,用空间换取时间 
     * 动态规划,对于第i个数,它一定是之前已存在数的2倍,3倍或5倍
     */
    int GetUglyNumber_Solution2(int index)
    {
        if(index <= 0)
            return 0;
    
        int *pUglyNumbers = new int[index];
        pUglyNumbers[0] = 1;
        int nextUglyIndex = 1;
    
        int *pMultiply2 = pUglyNumbers;
        int *pMultiply3 = pUglyNumbers;
        int *pMultiply5 = pUglyNumbers;
    
        while(nextUglyIndex < index)
        {
            int min = Min(*pMultiply2 * 2, *pMultiply3 * 3, *pMultiply5 * 5);
            pUglyNumbers[nextUglyIndex] = min;
    
            while(*pMultiply2 * 2 <= pUglyNumbers[nextUglyIndex])
                ++pMultiply2;
            while(*pMultiply3 * 3 <= pUglyNumbers[nextUglyIndex])
                ++pMultiply3;
            while(*pMultiply5 * 5 <= pUglyNumbers[nextUglyIndex])
                ++pMultiply5;
    
            ++nextUglyIndex;
        }
    
        int ugly = pUglyNumbers[nextUglyIndex - 1];
        delete[] pUglyNumbers;
        return ugly;
    }