Big Number Problem

来源:互联网 发布:mysql count函数 编辑:程序博客网 时间:2024/06/13 13:29
 题目来源: PKU ACM             Problem 1423
Big Number
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 5495 Accepted: 1725

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

涉及到大整数阶乘的问题, 这里只需要得到结果的位数, 因此没有必要得到精确的结果, 用Bit(n) 来表示n的位数,
有Bit(n) = [lgn] + 1; ([n]表示取下整数), 这样的话就可以得到
Bit(n!) = [logn + log(n-1) + ......  + log2] + 1
通过这个公式可以得到以下代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

// pi
#define PI 3.1415926535897932384
// e
#define E  2.7182818284590452354

int main()
{
    // 输入的个数
    int inputNumber;
    // 存储输入的数(int是32位)
    int *inputs;
    // 存储输出的结果
    int *outputs;

    int i, j;
    double temp;

    scanf("%d", &inputNumber);
    inputs = (int *)malloc(inputNumber*sizeof(int));
    outputs = (int *)malloc(inputNumber*sizeof(int));

    for (i = 0; i < inputNumber; i++)
    {
        scanf("%d", &inputs[i]);
        // temp保存求和的结果,每次清零
        temp = 0;
        for (j = 2; j <= inputs[i]; j++)
        {
            temp += log10(j);
        }
        // 将结果转换成Int型
        outputs[i] = (int)temp + 1;
    }

    for (i = 0; i < inputNumber; i++)
    {
        printf("%d/n", outputs[i]);
    }
   
    return 0;
}
提交代码发现运行超时, 上网查资料后发现有一个stirling公式,可以直接求得.


根据这个公式可以得到以下代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

// pi
#define PI 3.1415926535897932384
// e
#define E  2.7182818284590452354

int main()
{
    int inputNumber;
    int *inputs;

    int *outputs;

    int i;
    int temp;

    scanf("%d", &inputNumber);
    inputs = (int *)malloc(inputNumber*sizeof(int));
    outputs = (int *)malloc(inputNumber*sizeof(int));

    for (i = 0; i < inputNumber; i++)
    {
        scanf("%d", &inputs[i]);
        temp = inputs[i];
        outputs[i] = (int)(0.5*log10(2*PI*temp) + temp*log10(temp/E)) + 1;
    }

    for (i = 0; i < inputNumber; i++)
    {
        printf("%d/n", outputs[i]);
    }
   
    return 0;
}
运行后结果是正确的, 而且时间消耗极少,提交便可通过了.
关于stirling公式的资料可以上网搜一下.
原创粉丝点击