hdu1141(二进制数位,二分,打表)

时间:2024-04-15 00:05:33

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1141

题意:××公司是制造computer的,1960年它造的computer是4bit的,之后每10年翻倍;

有一个衡量computer的标准,就是它最大可以存下n!(无符号位),那么它就是n级;

求x年时该公司的电脑为几级(1960<= x <=2160);

思路:2160年时computer是4×pow(2, 20)=4194304bit,那么能储存的最大数大概为pow(2, 4194304)数量级,直接暴力求n显然是不可能的;

我们可以打表求n!二进制表示有多少位,再二分即可;

用a(n)表示n!二进制多少位;

有:a(n!) = (int)log2(n!) + 1 ;

由对数运算可得:a(n!) = int(log2(1)+log2(2)...+log2(n)) + 1;

http://www.cnblogs.com/geloutingyu/p/5978149.html (10进制数位求法及证明(hdu1018),与二进制类似,这里的二进制就不再证明啦)

代码:

 #include <iostream>
#include <math.h>
#include <algorithm>
#include <stdio.h>
#define MAXN 400000
using namespace std; int a[MAXN]; void meter(void){ //**打表,数组a中储存下标i对应阶乘的二进制位数
double cnt = ;
for(int i=; i<MAXN; i++){
cnt += log2(i);
a[i] = (int)cnt+;
}
} int main(void){
meter();
int n;
while(scanf("%d", &n)&&n!=){
int cnt = (n-)/;
int ans = *pow(, cnt);
int pos = lower_bound(a, a+MAXN, ans)-a;
if(a[pos]>ans){
pos--;
}
printf("%d\n", pos);
}
return ;
}