蓝桥杯: 大阶乘计算

蓝桥杯:基础练习 阶乘计算

问题描述
  输入一个正整数n,输出n!的值。
  其中n!=123*…*n。
  
算法描述

  • n!可能很大,而计算机能表示的整数范围有限,需要使用高精度计算的方法。使用一个数组A来表示一个
    大整数a,A[0]表示a的个位,A[1]表示a的十位,依次类推。
  • 将a乘以一个整数k变为将数组A的每一个元素都乘以k,请注意处理相应的进位。
    首先将a设为1,然后乘2,乘3,当乘到n时,即得到了n!的值。

输入格式
  输入包含一个正整数n,n<=1000。
  
输出格式
  输出n!的准确值。
  
样例输入

10

样例输出

3628800

思路

  • 逐位相乘
  • 处理进位

需要注意的是,对于最高位的进位处理,不止进行一次!
原因:可能最高位是一个很大的数

比如1234,那么进位之后,最高位是123,次高位是4
但是如果是12345678987654321,进位后最高位是1234567898765432,次高位是1,那么下一次乘法的时候,最高位乘上阶乘的那个数,最高位会溢出,即使用long long 也会 !!!

多次对高位进位

while(a[len-1] > 9)
{
	a[len] = (a[len-1] - a[len-1]%10)/10;
	a[len-1] = a[len-1] % 10;
	len += 1;
}

如果没有多次进位

会发现最高位非常大以至于溢出
在这里插入图片描述

AC完整代码

#include <iostream>

using namespace std;

typedef long long ll;

#define maxlen 1000000
ll a[maxlen];
ll len;

// 乘法,当前数 * x 
void mul(ll x)
{
	// 逐位相乘 
	for(ll i=0; i<len; i++)
	{
		a[i] *= x;
	}
	
	// 处理进位 
	for(ll j=0; j<len-1; j++)
	{
		a[j+1] += (a[j] - a[j]%10)/10;
		a[j] = a[j] % 10;
	}
	
	// 注意此处,需要 while 多次处理 
	while(a[len-1] > 9)
	{
		a[len] = (a[len-1] - a[len-1]%10)/10;
		a[len-1] = a[len-1] % 10;
		len += 1;
	}
}

void out()
{
	for(ll i=len-1; i>=0; i--)
	{
		cout<<a[i];
	}
	cout<<endl;
}

int main()
{
	a[0] = 1;
	ll n;
	len = 1;
	cin>>n;
	
	for(ll i=2; i<=n; i++)
	{
		mul(i);
	}
	
	out();
	
	return 0;
}
发布了18 篇原创文章 · 获赞 0 · 访问量 136

猜你喜欢

转载自blog.csdn.net/weixin_44176696/article/details/103963644
今日推荐