HDU1058 Humble Numbers DP问题

Humble Numbers

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


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.
 

题意:找出所有只含因数2、3、5、7的数字并输出    

    之前比赛的时候队友暴力打表,提示代码超限(当时真是没想到23333)
    后来用的vector过的,不过比较麻烦,需要去重和排序。
    一直对这题耿耿于怀,因为蓝桥杯有一道类似的题目我也被卡住了,很难受,结果拖到现在才来补题

    后来发现这题很少有详细的题解,所以我尝试写一发

    首先我们知道至少有5个数符合条件,分别是1,2,3,5,7.
    那么之后我们会想到利用2,3,5,7这几个因数不断利用已经得出的结果相乘
    比如对1,2,3,5,7分别乘以2得到2,4,6,10,14
    那么现在我们有1,2,3,4,5,6,7,10,14
    之后对于现有的数组都乘以3
    会得到1,2,3,4,5,6,7,9,10,14,15(这里15之后的数我就不写了,实在太累了233)
    乘以5,会得到1,2,3,4,5,6,7,9,10,14,15 (同理15之后的数字在以后省略)
    乘以7,仍是1,2,3,4,5,6,7,9,10,14,15
    之后再乘以2,这时会有1,2,3,4,5,6,7,9,10,12,14,15
    注意一下,这个时候前15个数据才会完整体现出来!!!
    普通因数相乘比较麻烦,所以dp处理
    pos是记载这个因数处理到第几个数字了(这个数字指的是最后的结果数组)
    因为我们会让所有的数字都乘以2,3,5,7,所以pos都从1开始,并随之不断更新
    注意pos更新的时候会自动过滤掉重复的数字,比如2*3=6和3*2=6


#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
long long a[6000];
int main()
{
    a[1]=1;
    int pos1=1,pos2=1,pos3=1,pos4=1;
    long long n1,n2,n3,n4;
    for(int i=2; i<=5842; i++)
    {
        a[i]=min(min(n1=a[pos1]*2,n2=a[pos2]*3),
                 min(n3=a[pos3]*5,n4=a[pos4]*7));  ///找到当前最小,因为只有这样才能确保最后的结果数组是有序的
        if(a[i]==n1) /// 这里千万不要加else,否则就会出现重复的数字
            pos1++;
        if(a[i]==n2)  
            pos2++;
        if(a[i]==n3)
            pos3++;
        if(a[i]==n4)
            pos4++;
    }
    int num;
    while(~scanf("%d",&num)&&num) ///输出巨坑
    {
        printf("The %d",num);
        if (num % 100 != 11 && num % 10 == 1)
        {
            printf("st");
        }
        else if (num % 100 != 12 && num % 10 == 2)
        {
            printf("nd");
        }
        else if (num % 100 != 13 && num % 10 == 3)
        {
            printf("rd");
        }
        else
        {
            printf("th");
        }
        printf(" humble number is %lld.\n",a[num]);
    }
}


猜你喜欢

转载自blog.csdn.net/qq_41548233/article/details/80314600