HDU 1058 Humble Numbers

来源:互联网 发布:石原慎太郎 知乎 编辑:程序博客网 时间:2024/05/16 02:54

Humble Numbers

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 1014 Accepted Submission(s): 548 
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
1234111213212223100100058420
 
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,四个为基数,逐个取最小值
找到合适的(有点类似筛选法的思想)!!!!,不过代码中有几个很值得注意的地方,好好看
#include<iostream>#include<cstdio>#include<cstring>using namespace  std;#define min(a,b)  a>b?b:a#define min(a,b,c,d)  min(min(a,b),min(c,d))long long  a[5843];int main(){    int p5=1,p2=1,p3=1,p7=1,k=1;    a[1]=1;    while(a[k]<=2000000000)    {     a[++k]=min(2*a[p2],3*a[p3],5*a[p5],7*a[p7]);     if(a[k]==2*a[p2]) p2++;     if(a[k]==3*a[p3]) p3++;     if(a[k]==5*a[p5]) p5++;     if(a[k]==7*a[p7]) p7++;//注意不能if,,,else if,,else if
                                  这样写,因为一个数可能同时对应几种情况
                                 例如a[k]==2*a[p2]==3*ap[3];如果这样写
                                 p2,p3中就只有一个++了,而另外一个必定会对
                                   接下来的判断造成干扰。    }    int n;    while(~scanf("%d",&n)&&n)    {        if(n%10==1&&n%100!=11)            printf("The %dst humble number is %lld.\n",n,a[n]);        else if(n%10==2&&n%100!=12)            printf("The %dnd humble number is %lld.\n",n,a[n]);        else if(n%10==3&&n%100!=13)            printf("The %drd humble number is %lld.\n",n,a[n]);        else            printf("The %dth humble number is %lld.\n",n,a[n]);    }
      /***好好体会本处对英文字母次序的输出处理,注意11,12,13这三个特殊
                                          的数字    return 0;}
再贴上自己的错误代码
#include<iostream>#include<cstdio>#include<cstring>using namespace std;long long a[5843];int flag[10001];int main(){    int n;    memset(a,0,sizeof(a));    memset(flag,0,sizeof(flag));    for(int i=1;i<=9;i++)       {           a[i]=i;           flag[i]=1;       }    int ge=10,flag2;    for(long long i=10;ge<=5842;i++)        {            long long  temp=i;            flag2=1;            for(;flag2;)            {                flag2=0;                if(temp%2==0)  {temp/=2;flag2=1;}                else if(temp%3==0)  {temp/=3;flag2=1;}                else if(temp%5==0)  {temp/=5;flag2=1;}                else if(temp%7==0)  {temp/=7;flag2=1;}                if(temp<=10000)                  if(flag[temp])                    {                      a[ge]=i;                      ge++;                      if(i<=10000)                      flag[i]=1;                      break;                    }            }        }    while(~scanf("%d",&n)&&n)    {        if(n%10==2)            printf("The %dnd humble number is %lld\n",n,a[n]);        else if(n%10==3)            printf("The %drd humble number is %lld\n",n,a[n]);        else            printf("The %dth humble number is %lld\n",n,a[n]);    }    return 0;}
很明显一个是直接求出,而下面的这个错误代码则是逐个判断
 
0 0
原创粉丝点击