zoukankan      html  css  js  c++  java
  • 丑数

    只包含因子2,3,5的数称作丑数。要求按从小到大的顺序输出指定数量的丑数。

    有2中方法:

    第一种:用穷举法,从最小的1开始判断穷举,是丑数就输出,否则继续循环判断。判断的方法是:如果一个数能被2整除,我们把他连续除以2;如果能被3整除,我们把他连续除以3;如果能被5整除,我们把他连续除以5。如果最后得到的值为1,那么这个数就是丑数。具体代码如下:

     1 ////////////丑数///////////////////////
     2 
     3 bool isUgly(int number)
     4 {
     5     assert(number > 0);
     6     while (number % 2 == 0)
     7     {
     8         number /= 2 ;
     9     }
    10     while (number % 3 == 0)
    11     {
    12         number /= 3 ;
    13     }
    14     while (number % 5 == 0)
    15     {
    16         number /= 5 ;
    17     }
    18 
    19     return (number == 1) ? true : false ;
    20 }
    21 void GetUgly1(int index)
    22 {
    23     if (index <= 0)
    24     {
    25         return;
    26     }
    27     int number = 0 ;
    28     int count = 0 ;
    29     while (count < index)
    30     {
    31         ++number;
    32         if (isUgly(number))
    33         {
    34             count++ ;
    35             cout<<number<<endl;
    36         }
    37     }
    38 }
    1 int main()
    2 {
    3     unsigned long  start_time = GetTickCount(); 
    4     GetUgly1(1000);
    5     unsigned long  end_time = GetTickCount(); 
    6     cout<<"The run time is: "<<(end_time-start_time)<<"ms!"<<endl;//输出运行时间
    7     getchar();
    8     return 0;
    9 }

    输出1000个丑数的结果如下图:

    第二种:

    用空间换时间,创建一个数组,里面的数字是排好序的丑数,下一个丑数是前面丑数乘以2、3、5得到的大于当前最大丑数的最小一个数。和第一种思路相比,第二种思路不需要在非丑数上做任何计算,因此时间效率会明显提升,但增加了空间消耗。具体代码如下:

     1 int Min(int num1 , int num2 , int num3)
     2 {
     3     int min = (num1 < num2) ? num1 : num2 ;
     4     return (min < num3) ? min : num3 ;
     5 }
     6 
     7 
     8 void GetUgly2(int index)
     9 {
    10     if (index <= 0)
    11     {
    12         return ;
    13     }
    14     int* pUglyNumbers = new int[index];
    15     pUglyNumbers[0] = 1 ;
    16     int* pUglyNumbers2 = pUglyNumbers ;//指向丑数乘以因数2后得到的最大丑数的位置,起始位置为pUglyNumbers[0]
    17     int* pUglyNumbers3 = pUglyNumbers ;//指向丑数乘以因数3后得到的最大丑数的位置,起始位置为pUglyNumbers[0]
    18     int* pUglyNumbers5 = pUglyNumbers ;//指向丑数乘以因数5后得到的最大丑数的位置,起始位置为pUglyNumbers[0]
    19     int NextUgly = 1 ; //下一个丑数存储的位置
    20     while ( NextUgly < index )
    21     {
    22         int min = Min((*pUglyNumbers2) * 2 , (*pUglyNumbers3) * 3 , (*pUglyNumbers5) * 5) ;//取最小的值作为下一个丑数
    23         pUglyNumbers[NextUgly] = min ;
    24 
    25         while ((*pUglyNumbers2) * 2 <= min) //改变pUglyNumbers2的位置,使其指向后续所有丑数乘以因数2后得到的最大丑数
    26         {
    27             pUglyNumbers2++ ;
    28         }
    29         while ((*pUglyNumbers3) * 3 <= min) //改变pUglyNumbers3的位置,使其指向后续所有丑数乘以因数3后得到的最大丑数
    30         {
    31             pUglyNumbers3++ ;
    32         }
    33         while ((*pUglyNumbers5) * 5 <= min) //改变pUglyNumbers5的位置,使其指向后续所有丑数乘以因数5后得到的最大丑数
    34         {
    35             pUglyNumbers5++ ;
    36         }
    37 
    38         NextUgly++ ;
    39 
    40     }
    41 
    42     for (int i = 0 ; i < index ; i++)
    43     {
    44         cout<<pUglyNumbers[i]<<endl;
    45     }
    46 
    47     delete[] pUglyNumbers ;
    48 
    49 }
    50 
    51 int main()
    52 {
    53     unsigned long  start_time = GetTickCount(); 
    54     GetUgly2(1000);
    55     unsigned long  end_time = GetTickCount(); 
    56     cout<<"The run time is: "<<(end_time-start_time)<<"ms!"<<endl;//输出运行时间
    57     getchar();
    58     return 0;
    59 }

    输出1000个丑数的结果如下图:

    可以看见第二种方法时间效率提高了10多倍!!

  • 相关阅读:
    洛谷P1613 跑路
    洛谷P2149 Elaxia的路线
    洛谷P3119 草鉴定
    洛谷P1972 HH的项链
    洛谷P2458 保安站岗
    uva10061
    uva579
    uva 127 "Accordian" Patience
    uva10177 (2/3/4)-D Sqr/Rects/Cubes/Boxes?
    uva156
  • 原文地址:https://www.cnblogs.com/csxcode/p/3728318.html
Copyright © 2011-2022 走看看