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

题目链接: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

  然后就是二分查找,边界比较纠结。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #define LL long long 
 5 #define MAXN 216000+10
 6 #define min(a,b) ((a)<(b)?(a):(b))
 7 LL a[MAXN];
 8 int main(void) {
 9     int i, j, k, p;
10     i = j = k = 0; 
11     a[0] = 1;
12     for (p = 1; p <= 12690; ++p) {
13         a[p] = min(a[i]*2, min(a[j]*3, a[k]*5));
14         if (a[p] == a[i] * 2) ++i;
15         if (a[p] == a[j] * 3) ++j;
16         if (a[p] == a[k] * 5) ++k;
17     }
18     int T; scanf("%d",&T);
19     while (T--) {
20         LL n;
21         scanf("%I64d", &n);
22         int low = 1, high = 12690, mid, last;
23         LL goal;
24         goal = n;
25         while (low < high) {
26             mid = low + (high - low) / 2;
27             if (a[mid] < goal) low = mid + 1;
28             else if (a[mid] > goal) high = mid - 1;
29             else {last = mid; break;}
30         }
31         if (high == low) {
32             last = high;
33         }
34         else if (low > high) last = low;
35         if (goal == 1) last = 1;
36         if (a[last] < goal) last++;
37         printf("%I64d\n", a[last]);
38     }
39 
40     return 0;
41 }

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

posted on 2013-06-15 17:24  aries__liu  阅读(488)  评论(0编辑  收藏  举报