51nod 1010 只包含因子2 3 5的数 二分答案

K的因子中只包含2 3 5。满足条件的前10个数是:2,3,4,5,6,8,9,10,12,15。
所有这样的K组成了一个序列S,现在给出一个数n,求S中 >= 给定数的最小的数。
例如:n = 13,S中 >= 13的最小的数是15,所以输出15。
 
Input
第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 10000)
第2 - T + 1行:每行1个数N(1 <= N <= 10^18)
Output
共T行,每行1个数,输出>= n的最小的只包含因子2 3 5的数。
Input示例
5
1
8
13
35
77
Output示例
2
8
15
36
80
这道题并不算什么难题吧,但是可以熟悉下二分的各种奇淫做法,stl里面有三种二分还是很强大的

函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置

举例如下:

一个数组number序列为:4,10,11,30,69,70,96,100.设要插入数字3,9,111.pos为要插入的位置的下标

pos = lower_bound( number, number + 8, 3) - number,pos = 0.即number数组的下标为0的位置。

pos = lower_bound( number, number + 8, 9) - number, pos = 1,即number数组的下标为1的位置(即10所在的位置)。

pos = lower_bound( number, number + 8, 111) - number, pos = 8,即number数组的下标为8的位置(但下标上限为7,所以返回最后一个元素的下一个元素)。

所以,要记住:函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置,且last的位置是越界的!!~

返回查找元素的第一个可安插位置,也就是“元素值>=查找值”的第一个元素的位置 by飘过的小

10^18这个数据量还是很大的,不过2^10都1024了,所以对这些数枚举并不会有什么错错,但是关键是要对这些数字进行查找,就是找这些数第一个大于n的就可以了,这就是大致思路

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL INF = 1e18+1000;
const int MAXN = 1e6;
LL a[MAXN];
int cnt;
void Init()
{
    cnt = 0;
    for(LL i=1; i<INF; i*=2)
        for(LL j=1; j*i<INF; j*=3)
            for(LL k=1; i*j*k<INF; k*=5)
                    a[cnt++] = i*j*k;
}
int main()
{
    Init();
    sort(a,a+cnt);
    int t;
    cin>>t;
    while(t--)
    {
        LL n;
        scanf("%lld",&n);
        printf("%lld
",a[lower_bound(a+1,a+cnt+1,n)-a]);
    }
    return 0;
}
 
 
原文地址:https://www.cnblogs.com/BobHuang/p/6942258.html