题意:如果一个数他的质数因子中只含有2,3,5,7其中的一个 或多个,就称为丑数,求n以内的丑数;
思路:看了别人博客,他定义的丑数是2,3,5作为质因子,加了个7做法也一样;假设数组ugly[N]中存放不断产生的丑数,初始只有一个丑数ugly[0]=1,由此出发,下一个丑数由因子2,3,5竞争产生,得到ugly[0]*2, ugly[0]*3,ugly[0]*5, 显然最小的那个数是新的丑数,所以第2个丑数为ugly[1]=2,开始新一轮的竞争,由于上一轮竞争中,因子2获胜,这时因子2应该乘以ugly[1]才显得公平,得到ugly[1]*2,ugly[0]*3,ugly[0]*5,因子3获胜,ugly[2]=3,同理,下次竞争时因子3应该乘以ugly[1],即:ugly[1]*2,ugly[1]*3,ugly[0]*5, 因子5获胜,得到ugly[3]=5,重复这个过程,直到第n个丑数产生。总之:每次竞争中有一个(也可能是两个)因子胜出,下一次竞争中 胜出的因子就应该加大惩罚!
/*
*
* POJ 2247
* 分类:据说是动态规划。。。
*
*/
#include<stdio.h>
#include<string.h>
#define SIZE 5842
#define MAX 2000000001
int num[SIZE+1];
char rank[10];
void excel()
{
int i,j,prime[4],loc[4];
num[0]=1,loc[0]=loc[1]=loc[2]=loc[3]=0;
prime[0]=2,prime[1]=3,prime[2]=5,prime[3]=7;
for(i=1;i<=5842;i++)
{
int min=MAX;
for(j=0;j<4;j++)
if(num[loc[j]]*prime[j]<min)
min=num[loc[j]]*prime[j];
for(j=0;j<4;j++)
if(num[loc[j]]*prime[j]==min)
loc[j]++;
num[i]=min;
}
}
void make_ranked(int n) /*加数字后面的英语序数词,四级没过。。。网上查的*/
{
int last=n%10;
int seclast=(n%100)/10;
if( last>3||last==0) strcpy(rank,"th");
else if(last==3) strcpy(rank,"rd");
else if(last==2) strcpy(rank,"nd");
else strcpy(rank,"st");
if(last==1&&seclast==1) strcpy(rank,"th");
if( last==2&&seclast==1) strcpy(rank,"th");
if( last==3&&seclast==1) strcpy(rank,"th");
}
int main()
{
int n;
excel();
while(scanf("%d",&n)&&n)
{
make_ranked(n);
printf("The %d%s humble number is %d.\n",n,rank,num[n-1]);
}
return 0;
}