[ACM] hdu 1058 Humble Numbers

Humble Numbers

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 15013    Accepted Submission(s): 6525


Problem Description
A number whose only prime factors are 2,3,5 or 7 is called a humble number. The sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 24, 25, 27, ... shows the first 20 humble numbers. 

Write a program to find and print the nth element in this sequence
 

Input
The input consists of one or more test cases. Each test case consists of one integer n with 1 <= n <= 5842. Input is terminated by a value of zero (0) for n.
 

Output
For each test case, print one line saying "The nth humble number is number.". Depending on the value of n, the correct suffix "st", "nd", "rd", or "th" for the ordinal number nth has to be used like it is shown in the sample output.
 

Sample Input
1 2 3 4 11 12 13 21 22 23 100 1000 5842 0
 

Sample Output
The 1st humble number is 1. The 2nd humble number is 2. The 3rd humble number is 3. The 4th humble number is 4. The 11th humble number is 12. The 12th humble number is 14. The 13th humble number is 15. The 21st humble number is 28. The 22nd humble number is 30. The 23rd humble number is 32. The 100th humble number is 450. The 1000th humble number is 385875. The 5842nd humble number is 2000000000.
 

Source



解题思路:

一个humble数指素数因子只有2,3 , 5, 7的数,比如1(也是), 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 24, 25...而11就不是,因为11是它的素数因子。

第N个Humble数肯定是前n-1个数中的一个与(2,3,5,7)的乘积。 f[n]=min(f[a]*2,f[b]*3,f[c]*4,f[d]*5), a=b=c=d=1初始化。

对于2    有  1*2=2    2*2=4     ,6,8 10, 12, 14.。。。。

对于3    有  1*3=3    2*3=6    , 9,12, 15,18, 21.。。。。

对于5    有  1*5=5    2*5=10  ,15 ,20,25, 30,35.。。。。

对于7    有  1*7=7    2*7=7    ,21 ,28,35, 42,   49.。。。。

最开始a=b=c=d=1,取最小值2,f[2]=2,min(2,3,5,7) ,下一次取值时,原来的2不能用了,该f[2]*2=4了,所以下次取的时候,取最小值3,min(4,3,5,7),所以说当对于2的计数从1开始,只要被采纳选作Humble数,及计数器+1,这里的计数器其实是指对于每个数(2,3,5,7),f[i]的下标的计数器,即f[2]*2=4,为什么用f[a]*2呢,其实计数器是a,f[2]肯定比f[1]大,下一次应该使用4去参与和其它三个数的竞争,比最小。所以对于2,3,5,7每个数来说,只要自己被采用,自己的计数器就+1,再以5为例,初值1*5=5,该值被f[i]采纳为humble数,则下一次参与竞选Humble数该从10(f[2]*5)开始。考虑到每次竞选Humble数的时候有两个数相等,则这两个数的计数器都+1.  感觉没有说清楚。还得自己理解理解。

再举个简单的例子来说吧:

比如 一个数组中的元素已经从大到小排好序 如 num[4]={1, 3, 5,7},

再给定一个数,比如 2,求2与数组中元素的乘积排序是什么样子的。

因为数组中已经排好序,所以第一个数乘以2肯定是最小的,最小的找到了,那么第二个数乘以2肯定是次小的,以此类推,第三个数乘以2肯定为次次小的,第四个数乘以2肯定为最大的。其中的第一二三四个数,就相当于f[1],f[2],f[3]。。。。

代码:

#include <iostream>
#include <algorithm>
using namespace std;
int f[5843];

int min4(int a,int b,int c,int d)
{
    int m=min(min(a,b),min(c,d));
    return m;
}

int main()
{
    int a,b,c,d;
    a=b=c=d=1;
    f[1]=1;
    for(int i=2;i<=5842;i++)
    {
        f[i]=min4(f[a]*2,f[b]*3,f[c]*5,f[d]*7);
        if(f[i]==f[a]*2) a++;
        if(f[i]==f[b]*3) b++;
        if(f[i]==f[c]*5) c++;
        if(f[i]==f[d]*7) d++;
    }
    int n;
    while(cin>>n&&n)
    {
        if(n%10==1&&n%100!=11)
            cout<<"The "<<n<<"st humble number is "<<f[n]<<"."<<endl;
        else if(n%10==2&&n%100!=12)
            cout<<"The "<<n<<"nd humble number is "<<f[n]<<"."<<endl;
        else if(n%10==3&&n%100!=13)
            cout<<"The "<<n<<"rd humble number is "<<f[n]<<"."<<endl;
        else
            cout<<"The "<<n<<"th humble number is "<<f[n]<<"."<<endl;
    }
    return 0;
}


posted @ 2014-03-11 20:48  同学少年  阅读(148)  评论(0编辑  收藏  举报