POJ1423 与 HDOJ1018 BigNumber

题目如下:

Big Number

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 23400 Accepted: 7489

Description



In many applications very large integers numbers are required. Some of these applications are using keys for secure transmission of data, encryption, etc. In this problem you are given a number, you have to determine the number of digits in the factorial of the number.


Input
Input consists of several lines of integer numbers. The first line contains an integer n, which is the number of cases to be tested, followed by n lines, one integer 1 <= m <= 10^7 on each line.


Output
The output contains the number of digits in the factorial of the integers appearing in the input.


Sample Input

2
10
20


Sample Output

7
19
Source


Dhaka 2002


一开始的想法...就是对于每个输入,进行高精度乘法进行阶乘...然后算出阶乘结果的长度...对于菜鸟来说...脑海里没广阔的算法思路...也只有想到这个办法了..

然后写好了代码...样例过了耶....然后没想那么多...submit....结果....Runtime Error....... 郁闷,然后一直调数组长度....好了....没有RE....发现TLE....然后自己用10^7进行测试...等了三四秒才能显示出来.....结果想了半小时....没思路....然后就开始百度....最后找到一些思路是使用一些数学公式来求的....

具体思路有两种。

第一种是(第一类斯特林公式?)


用这个方法的话在POJ的话,会超时,数据有点变态....应该有接近10^7的数据....


第二种是(第二类斯特林公式?)


用这种公式的话...样例过了....POJ过不了(WA)....HDOJ过了....然后纠结了....然后继续研究为什么POJ过不了,发现...对于这个公式...

如果用

len = (0.5*log(2.0*PI*k) + k*log((double)k) - k) / log((double)10) + 1;
这样的代码...对于k=1的情况,len为0.....自己也用计算器算了一下...发现..

len(k = 1)  = (0.5*log(2.0*PI*k) + k*log((double)k) - k) / log((double)10) = -0.03520....

所以才会出现WA的情况...在HDOJ过了的原因大概因为测试数据没有1这种情况吧....


以下是提交代码....其中注释部分是第一种思路的,没注释就是第二种思路的...

#include<iostream>
#include<cmath>
#define PI 3.1415926
using namespace std;
int main()
{
	long k;
	int n;
	double len;
	cin >> n;
	while(n--)
	{
		cin >> k;
		/*len = 1;
		while(k>0)
		{
			len += log10((double)k);
			k--;
		}*/
		if(k != 1)
			len = (0.5*log(2.0*PI*k) + k*log((double)k) - k) / log((double)10) + 1;
		else
			len = 1;
	
		cout << (long)len << endl;
	}
	return 0;
}

就先写到这里....希望自己对于相对来说比较简单的题目尽快动手去做做...好久没有写过代码了...继续加油吧!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值