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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值