标签:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1058
题意:丑数是指只有2,3,5 or 7这几个素因数的数(所以1也是丑数),找到第n个丑数。
思路:除了2,3,5,7任何一个丑数都是由另一个丑数乘上2,或3,或5,或7得到的。
所以可以用优先队列,每取出一个丑数就入队他们乘上2,3,5,7得到的四个丑数,这样每个丑数都生成了。复杂度还是不错的,不过按这种方法会生成比较大的数,最终爆掉int,所以要用long long
//93MS 1228K
#include<cstdio>
#include<cstring>
#include<queue>
#define ll long long
using namespace std;
ll ans[6000];
int main()
{
priority_queue<ll,vector<ll>,greater<ll> >que;
que.push(1);
int cnt=0;
while(!que.empty()){
if(cnt==5842) break;
ll t=que.top();
que.pop();
if(t<=ans[cnt]) continue;
ans[++cnt]=t;
que.push(t*2);
que.push(t*3);
que.push(t*5);
que.push(t*7);
}
int n;
while(~scanf("%d",&n)&&n){
if(n%10==1&&n%100!=11)printf("The %dst humble number is %I64d.\n",n,ans[n]);
else if(n%10==2&&n%100!=12)printf("The %dnd humble number is %I64d.\n",n,ans[n]);
else if(n%10==3&&n%100!=13) printf("The %drd humble number is %I64d.\n",n,ans[n]);
else printf("The %dth humble number is %I64d.\n",n,ans[n]);
}
return 0;
}每个丑数乘上2,3,5,7都会生成另一个丑数,而且第2个丑数一定是第一个丑数乘2,3,7,5得到的四个数中最小的,第三个丑数肯定是第一个丑数乘3,7,5(第一个丑数乘2已用掉)和第二个丑数乘2得到的四个数中的最小值。
可以看出把乘的2,3,7,5当作对象,每次生成下一个丑数一定是2,3,7,5乘以当前最靠前的且没乘过的数。
所以用尺取法把四个乘数当成对象,设成4个坐标,初始化成1,一步一步向前推进,直到推进n次,复杂度O(N),很优。
//93MS 1112K
#include<stdio.h>
#include<algorithm>
#include<cstring>
using namespace std;
int ans[5850];
int main()
{
int n;
int a,b,c,d;
ans[1]=1;
a=b=c=d=1;
int m=1;
while(m <= 5842)
{
int tmp=min(min(2*ans[a], 3*ans[b]), min(5*ans[c], 7*ans[d]));//生成下一个丑数
ans[++m]=tmp;
//向前推进
if(tmp==2*ans[a]) a++;
if(tmp==3*ans[b]) b++;
if(tmp==5*ans[c]) c++;
if(tmp==7*ans[d]) d++;
}
while(~scanf("%d",&n) && n)
{
printf("The %d",n);
if(n % 10 == 1 && n % 100 != 11)
printf("st");
else if(n % 10 == 2 && n % 100 != 12)
printf("nd");
else if(n % 10 == 3 && n % 100 != 13)
printf("rd");
else
printf("th");
printf(" humble number is %d.\n",ans[n]);
}
return 0;
}标签:
原文地址:http://blog.csdn.net/kalilili/article/details/43747641