点头1010 只包含因子2 3 5的数

June 15, 2013

题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1010 题目思路:   想想怎么打表吧,还有,只需要存下满足要求的数字,要求的数字可以表示为:(2^x*3^y*5^z),然后可以发现:2^60>10^18,所以,枚举的上限是60*60*60,大约是216000,实际上,只有1万多。枚举的方法就是以前做过的题目了:http://poj.org/problem?id=1338   然后就是二分查找,边界比较纠结。


#include <cstdio>
#include <cstring>
#include <cstdlib>
#define LL long long 
#define MAXN 216000+10
#define min(a,b) ((a)<(b)?(a):(b))
LL a[MAXN];
int main(void) {
    int i, j, k, p;
    i = j = k = 0; 
    a[0] = 1;
    for (p = 1; p <= 12690; ++p) {
        a[p] = min(a[i]*2, min(a[j]*3, a[k]*5));
        if (a[p] == a[i] * 2) ++i;
        if (a[p] == a[j] * 3) ++j;
        if (a[p] == a[k] * 5) ++k;
    }
    int T; scanf("%d",&T);
    while (T--) {
        LL n;
        scanf("%I64d", &n);
        int low = 1, high = 12690, mid, last;
        LL goal;
        goal = n;
        while (low < high) {
            mid = low + (high - low) / 2;
            if (a[mid] < goal) low = mid + 1;
            else if (a[mid] > goal) high = mid - 1;
            else {last = mid; break;}
        }
        if (high == low) {
            last = high;
        }
        else if (low > high) last = low;
        if (goal == 1) last = 1;
        if (a[last] < goal) last++;
        printf("%I64d\n", a[last]);
    }

    return 0;
}

输入输出原来要用%I64d,这个WA了两次……A了之后竟然是第一名,呵呵,可能大家都没有手写二分,都用的STL吧。

comments powered by Disqus