方法一:
/*
这种方法是通过暴力来解题。
*/
#include <iostream>
#include <stdio.h>
#include <algorithm>
#define MAXN 1000000
#define MAXM 1000000000000000100//注意:这里只填18个0不可以,还要加上100才能通过
//const long long MAXM = 1e18 + 100;
using namespace std;
long long num[MAXN];
int main(void)
{
int count = 0;
long long x = MAXM;
for (long long i = 1; i < MAXM; i *= 2)
for (long long j = 1; i*j < MAXM; j *= 3)
for (long long k = 1; i*j*k < MAXM; k *= 5)
num[count++] = i * j * k;
//这里是把符合题意并且小于MAXM的数字全部存入数组之中
sort(num, num + count);
int T;
scanf_s("%d", &T);
while (T--)
{
long long n;//注意,这里必须是long long,如果是int不能通过
scanf_s("%lld", &n);
if (n == 1)//因为1在数组中能够找到,但是它并不是2 3 5的因数,它应该输出的是它的下一个数2
printf("2\n");//因此我这里将它特殊化的拿出来等于2
else
printf("%lld\n", *lower_bound(num, num + count, n));//用二分搜索来节省时间
}
return 0;
}
方法二:
/*
略有一些技巧
*/
#include <iostream>
#include <stdio.h>
#include <algorithm>
#define MAXN 11000//
using namespace std;
long long num[MAXN];
long long minnum(long long x, long long y, long long z)
{//用来求三个数的最大值
long long temp = (x > y) ? y : x;
return (temp > z) ? z : temp;
}
void ugly(void)
{
long long A = 2, B = 3, C = 5;//这三个数表示的是当前倍数数字的最小值
int idex2 = 0, idex3 = 0, idex5 = 0;//这三个数字表示用来乘过的次数
num[0] = 1;//第一个数字为1,因为它乘什么就得什么
for (int i = 1; i < MAXN; i++)
{//计算前MAXN个元素,这个数组一直都在乘是增长得很快的
long long m = minnum(A, B, C);
num[i] = m;//把三个数字的最小值赋予num[i]以保证它的顺序
if (A == m)//三个数的最小值是A
A = 2 * num[++idex2];//那就在数列的下一个值来乘二,增大了A,并且保证了其最小
if (B == m)
B = 3 * num[++idex3];
if (C == m)
C = 5 * num[++idex5];
}
}
int main(void)
{
ugly();
int T;
scanf_s("%d", &T);
while (T--)
{
long long n;
scanf_s("%lld", &n);
if (n == 1)
printf("2\n");
else
printf("%lld\n", *lower_bound(num, num + MAXN, n));
}
return 0;
}