poj-2661-Factstone Benchmark

解题思路:在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;
}



你可能感兴趣的:(poj-2661-Factstone Benchmark)