题目描述
当一个数n的质因子只含有2,3,5的时候,我们可以将n称为235数(事实上叫丑数)。
那么,问题来了,给你一个数n,你能求出第一个大于等于n的235数是多少吗?编程解决这个简单的问题吧~
输入
多组输入
第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 30000)
第2 - T + 1行:每行1个数N(1 <= N <= 10^18)
输出
共T行,每行1个数,输出>= n的最小235数。
样例输入 复制
5 1 8 13 35 77
样例输出 复制
2 8 15 36 80
提示
前10个235数是:2,3,4,5,6,8,9,10,12,15
1.这一题不能暴力解决,时间很可能超限。我们要提前算好存在数组里面,然后去访问它,即可
2. 我刚开始想的是2,3,5乘以递增的数k2,k3,k5,后面发现k2,k3,k5递增的时候很可能变成不是2,3,5的素数,就不会符合题意。但是如果再加判断的话,时间复杂度就增加了。
3.后面发现,在后面的丑数是可以通过前面的丑数来*2,*3,*5得到的,但是不一定是连续的下标,所以我把k2,k3,k5当成了下标,代表分别能*2,*3,*5。
4.我们把第一个丑数当作1,并提前记入预存的数组a数组中,k2,k3,k4都是由记录1的下标开始延生数字的,所以k2=k3=k5=0。
5.然后比较当a[k2]*2,a[k3]*3,a[k5]*5时,谁最小,然后存下来,在写比较最小的数的时候,一定要记得会出现等于的情况,我们按顺序来,如果a[k2]*2<=a[k3]*3或者a[k5]*5,就当作a最大,依次类推咯。
6.大家可能会有一点疑惑,想15这个数字,它既能被3除又能被5除,那怎么办,我们写代码的时候判断情况不要写else,因为这个数可能会被2个或者3个数整除,我们判断它们是否整除,如果是,我们就把能整除的kn++即可。
代码如下:
#include<stdio.h>
#define N 30010
long long a[N]={1},s[N];
long long min(long long a,long long b,long long c)
{
if(a<=b&&a<=c) return a;
else if(b<=a&&b<=c) return b;
else return c;
}
void uglynumber()//2*3,3*5
{
long long i,j,k2=0,k3=0,k5=0,s;
for(i=1;i<N;i++)
{
a[i]=min(a[k2]*2,a[k3]*3,a[k5]*5);
if(a[i]==a[k2]*2) k2++;
if(a[i]==a[k3]*3) k3++;
if(a[i]==a[k5]*5) k5++;
}
}
long long seek(long long s)
{
int i;
for(i=1;i<N&&a[i]<s;i++);
return a[i];
}
int main()
{
int t,i;
uglynumber();
//scanf("%d",&t);
while(~scanf("%d",&t))
{
for(i=0;i<t;i++)
{
scanf("%lld",&s[i]);
}
for(i=0;i<t;i++)
{
printf("%lld\n",seek(s[i]));
}
}
}