SCU - 1689 算阶乘(10000的阶乘)

题目:

Description

求给定数的阶乘。

输入

    第一行为测试数据的组数n,后面有n个测试数据。每组测试数据一行,为一个不超过10000的非负整数。
    可以保证,最后运算结果以十进制表示不会超过36000位。

输出

    对于每组测试数据,输出一行,即相应的阶乘。

输入示例

3
2
3
4

输出示例

2
6
24

用数组来自定义整数的存储、乘法、输出,把1个数按照每5位切开,存到1个数组里面。

代码:

#include<iostream>
#include<stdio.h>
#include<iomanip>
using namespace std;

int list[1002][7201];
int l[11][7201];

void f(int n, int k)	//k从0到10
{
	for (int j = 1; j <= 7200; j++)l[0][j] = list[n][j];
	for (int i = 1; i <= k; i++)
	{
		for (int j = 1; j <= 7200; j++)l[i][j] = l[i - 1][j] * (10 * (n - 1) + i);
		int temp = 0;
		for (int j = 1; j <= 7200; j++)
		{
			l[i][j] += temp;
			temp = l[i][j] / 100000;
			l[i][j] %= 100000;
		}
	}
}

void build()
{
	for (int i =2; i <= 1001; i++)
	{
		f(i - 1, 10);
		for (int j = 1; j <= 7200; j++)list[i][j] = l[10][j];
	}
}

void out(int n)
{
	int k = n - n / 10 * 10;
	f(n / 10 + 1, k);
	bool flag = false;
	for (int j = 7200; j > 0; j--)
	{
		if (flag)printf("%05d", l[k][j]);
		else if (l[k][j])
		{
			printf("%d", l[k][j]);
			flag = true;
		}
	}
}

int main()
{
	int t, n;
	cin >> t;
	for (int j = 7200; j > 0; j--)list[1][j] = 0;
	list[1][1] = 1;
	build();
	while (t--)
	{
		cin >> n;
		out(n);
		cout << endl;
	}
	return 0;
}

这个代码AC了。440ms

虽然build算出了1到10000所有数的阶乘,但是只存了1001个。

我做了测试,测试内容很简单,如果n是10000就输出1,结果就不能AC了。也就是说,测试数据刚好是到10000的。

我用word统计了一下,10000!有35660位。所以只能通过稀疏存储来防止爆内存。

f中的参数k是0到9,f在2个地方被调用。

build中调用的f的参数k都是10,out中都是0到9,还是挺有意思的。


然而,用java来写就简单多了。

代码:

import java.util.*;
import java.math.BigInteger;
public class Main {

    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        int k=Integer.parseInt(cin.nextLine());
        while(k-->0)
        {
            int n=Integer.parseInt(cin.nextLine());
            BigInteger s=new BigInteger("1");
            for(int i=1;i<=n;i++)s=s.multiply(BigInteger.valueOf(i));
            System.out.println(s.toString());
        }
        
    }
}

你可能感兴趣的:(SCU - 1689 算阶乘(10000的阶乘))