点头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吧。