这应该是除了数的读法 (if判断有点烦,以后再花时间去理) 之外,所有的基础练习到此告一段落,接下来需要取学习更多的算法,不断的去提高,向着 蓝桥杯——算法训练环节开冲咯,小白一定会变大白的,奥里给
资源限制
时间限制:1.0s 内存限制:512.0MB
问题描述
输入一个正整数 n n n,输出 n ! n! n!的值。
其中 n ! = 1 ∗ 2 ∗ 3 ∗ … ∗ n n!=1*2*3*…*n n!=1∗2∗3∗…∗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
将a乘以一个整数k变为将数组A的每一个元素都乘以k,请注意处理相应的进位。
首先将a设为1,然后乘2,乘3,当乘到n时,即得到了n!的值。(由于不知道n!最大多大,我们开个100000长度数组,代表最后的数字长度,不是位数哦)
根据题目的要求,自己将所某一次乘法的计算过程给展示出来,结合代码里注释应该就都能理解了,这里假设当前步骤的大数数组是{0,1,1,1,1,1,0,0,0,…,0}(也可以字符串直接操作),这里为了下标方便多开一些空间了
a[1] | a[2] | a[3] | a[4] | a[5] | a[6] | a[7] | … |
---|---|---|---|---|---|---|---|
1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 |
123 | 123 | 123 | 123 | 123 | 0 | 0 | 0 |
3 | 123+12 | 123 | 123 | 123 | 0 | 0 | 0 |
— | 5 | 123+13 | 123 | 123 | 0 | 0 | 0 |
— | — | 6 | 123+13 | 123 | 0 | 0 | 0 |
— | — | — | 6 | 123+13 | 0 | 0 | 0 |
— | — | — | — | 6 | 0+13 | 0 | 0 |
— | — | — | — | — | 3 | 0+1 | 0 |
— | — | — | — | — | — | 1 | 0 |
3 | 5 | 6 | 6 | 6 | 3 | 1 |
如上述表格所示,这个就是在计算阶乘的循环里,大数的计算过程,如下所示:
a [ i ] = ( a [ i − 1 ] + 进 位 ) % 10 (1) a[i]=(a[i-1]+进位)\%10 \tag{1} a[i]=(a[i−1]+进位)%10(1)
a [ i ] 来 自 a [ i − 1 ] 的 进 位 = ( a [ i − 1 ] + ( a [ i − 1 ] 来 自 a [ i − 2 ] 的 进 位 ) ) / 10 (2) a[i]来自a[i-1]的进位 = (a[i-1]+(a[i-1]来自a[i-2]的进位))/10 \tag{2} a[i]来自a[i−1]的进位=(a[i−1]+(a[i−1]来自a[i−2]的进位))/10(2)
多出来的进位,意味这一次的计算比原来的数大,需要进位,比如最后多出的13的位是比万位高的,分别是百万位,十万位
(博主语言能力表达有限,比较菜菜,见谅呀)
#include
#include
#define MAX 100000
using namespace std;
int a[MAX];
int main(){
int n;
cin>>n;
a[1]=1; //个位的数字是a[1]
/*
x 代表当前的位数(就是表示有多少位)
y 代表当前的进位,由于每个数组的元素都要乘以一个数,这个数很大,就导致了进位,
原本数还需要加上进位结果,而x也随着进位y的变化而变化,将每一个y都分配
好,代表此次乘法结束
在某一位的进位的话就是进位%10
进位到高位的时候,缩小10倍,所以整除
*/
int pos_now=1,jw;
for(int i=2;i<=n;i++){
jw=0;
for(int j=1;j<=pos_now;j++){
int t = a[j]*i+jw; //临时的每一位*对应的i的结果,再加上在这个位置的进位就是真实结果
a[j] = t%10; //实际a[i]就是t取余
jw=t/10; //进位到高位的时候,缩小10倍,所以整除
}
//当到当前位数(实际上也是最大)x的时候,多出来的数还要进位
while(jw){
a[++pos_now]=jw%10;
jw/=10;
}
}
for(int i=pos_now;i>=1;i--){
cout<<a[i];
}
return 0;
}