解题思路:在1960年,字的大小是4位,以后每十年翻一番,就意味着,y年的字的位数为k=pow(2,(y-1960)/10),而k位的无符号整数是pow(2,k)-1,n!要小于等于pow(2,k)-1。直接进行求解容易溢出和超时,所以采用对数运算。n!<=pow(2,k)-1,两边取对数,log2(n)+log2(n-1)+...+log(1)<k。
c++代码如下:
<pre name="code" class="cpp">#include<iostream>
#include<cmath>
using namespace std;
int main()
{
int k,Y,i;
double sum,y;
while(cin>>y &&y)
{
k=pow((double)2,(y-1960)/10+2);//计算y年时的计算机位数k,注意pow()中的参数都要是double型
sum=0;//注意每次循环都要重新赋值0,不能放在循环外。
for(i=1;sum<k;i++)
sum+=log((double)i)/log((double)2); //C++中log()表示ln,没有log2的函数,要用换底公式,即log2(n)=ln(n)/ln(2) ;注意log()中的参数都要是double型
cout<<i-2<<endl;
}
return 0;
}
解题思路:在1960年,字的大小是4位,以后每十年翻一番,就意味着,y年的字的位数为k=pow(2,(y-1960)/10),而k位的无符号整数是pow(2,k)-1,n!要小于等于pow(2,k)-1。直接进行求解容易溢出和超时,所以采用自然对数运算。n!<=pow(2,k)-1,两边取自然对数,ln(n)+ln(n-1)+...+ln(1)<kln2。
C语言代码如下;
#include<stdio.h>
#include<math.h>
int main()
{
int y,Y,i;
double sum,k;
while(scanf("%d",&y)==1 &&y)
{
k=log(4);//即2ln2;
for(Y=1960;Y<=y;Y+=10)
k*=2; //当Y=1960时k为4ln2; 依次类推
sum=0;
i=1;
while(sum<k)
sum+=log((double)++i);//ln(n)+...+ln(1);
printf("%d\n",i-1);
}
return 0;
}