神奇的235数

题目描述

当一个数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]));
		}	
	}	
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值