航電1018 Big Number

Problem 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 ≤ n ≤ 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
 
Recommend
JGShining   |   We have carefully selected several similar problems for you:   1017  1016  1071  1019  1021 
 
 
/***********************************************************起初的代碼*********************************************************************
 
#include<iostream>
#include<cmath>
using namespace std;

int get(int m){
	int pass = 0;        //進位 
	int num[100];        //存儲位數 
	num[0] = 1;          //一個數的第幾位 
	int count = 0;       //記錄進位的位數 
	int s = 0;
	int number = 1;      //記錄數目的長度
	 
	for(int i=1;i<=m;i++){    //階乘 
		for(int j=0;j<number;j++){		 //數組須要操做有數的位置 
		    s = pass;	
			pass = (num[j]*i + pass)/10;  //肯定進位 
			num[j] = (num[j]*i + s)%10;	  //肯定後一位 
		} 
		s = pass;
       	while(pass > 0)                   //輸出進位的位數 多是1位數 多是2位數,多是3位數 。。。。 
		{
            count++;
            pass = pass/10;            
		}
		while(count){
			num[number] = s%10;           //存儲進位的值 
			number++;
			s = s/10;
			count--;
		}
        pass = 0;
	}
	return number;                       //返回長度 
}
int main(){
	int n;
	cin>>n;         //輸入須要計算數目 
	while(n--){
		int m;
		cin>>m;
		cout<<get(m)<<endl;   //獲得每一個樣例結果 
	}
} 

後面發現對於N!來講是比較快的了,可是對於n = 1000000時仍然會超時,因而乎決定不能這麼直接php

解題思路:ios

1.能夠暴力,N的階乖的位數等於LOG10(N!)=LOG10(1)+.....LOG10(N);
2.Stirling公式:n!與√(2πn) * n^n * e^(-n)的值十分接近
故log10(n!) = log(n!) / log(10) = ( n*log(n) - n + 0.5*log(2*π*n))/log(n);
參考的是: http://blog.csdn.net/ultimater/article/details/7884951
 
因而乎比較簡單
 
方法1:
#include<iostream>
#include<cmath>
using namespace std;

double get(int m){
    double cnt = 0;
	for(int i=2;i<=m;i++){
		cnt += log10(i);
	}
	return cnt;
}
int main(){
	int n;
	cin>>n;         //輸入須要計算數目 
	while(n--){
		int m;
		cin>>m;
		cout<<1+(int)get(m)<<endl;   //獲得每一個樣例結果 
	}
} 

 

方法2:git

#include<iostream>
#include<cmath>
using namespace std;
#define PI    3.141592653
#define ln10  log(10.0)

double get(int N){
    double cnt = 0;
    cnt = ceil((N*log(double(N))-N+0.5*log(2.0*N*PI))/ln10);
	return cnt;
}
int main(){
	int n;
	cin>>n;         //輸入須要計算數目 
	while(n--){
		int m;
		cin>>m;
		cout<<(int)get(m)<<endl;   //獲得每一個樣例結果 
	}
} 

關於log10()能夠參考 : https://msdn.microsoft.com/zh-cn/library/t63833dz.aspx;數組

關於ceil()函數,向上取整 ,能夠參考: https://baike.baidu.com/item/ceil/10931457?fr=aladdinapp

仍是數學公式好,死算的極可能GG函數

 
相關文章
相關標籤/搜索