POJ-Factstone Benchmark-2661 打表+二分
题目链接:http://poj.org/problem?id=2661
题意:amterl公司在1960年推出一款4bit的cpu,之后每十年推出一款bit翻倍的cpu,直到2160年。用cpu每次能表示的最大的n!(无符号数)来代表cpu的性能。输入y,表示年份。问该年amterl最新款cpu的性能,也就是cpu能表示的最大的n!,输出n。
思路:n! <= 2^k - 1 等价于 log2(n!) = log2(n) + log2(n-1) + ... +log2(1) <= log2(2^k -1) < k
用一个数组sum[i] 记录 log2(i!) , 查询最大的i,输出即可
代码:
#include <iostream> #include <algorithm> #include <math.h> #define ll long long #define maxn (1<<23) #define count_n 99 using namespace std; int k; int y; int ans; int lastn = 1; double sum_logn[maxn]; int biao[25]; void setbiao() { biao[0] = 1; for (int i = 1; i <= 24; i++) { biao[i] = biao[i - 1] << 1; } } void cin_k(int &k) { k = (y / 10) - 194; k = biao[k]; } void setlogn() { while (sum_logn[lastn]<k) { lastn++; sum_logn[lastn] = sum_logn[lastn - 1] + log((double)lastn) / log((double)2); } } int main() { setbiao(); scanf("%d", &y); while (y) { cin_k(k); if (k < sum_logn[lastn]) { int l = 1, r = lastn, mid; while (l!=r) { mid = (l + r) >> 1; if (sum_logn[mid + 1] < k) { l = mid + 1; } else r = mid; } ans = r; } else { setlogn(); ans = lastn - 1; } printf("%d\n", ans); scanf("%d", &y); } return 0; }