蓝桥杯 基础训练--阶乘计算(高精度)、高精度加法

蓝桥杯 基础训练--阶乘计算(高精度)

题目

问题描述
  输入一个正整数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

代码及注释

#include <iostream> 
#include <stdlib.h>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#define max 4000
using namespace std;
 
int main ()
{
int n;
cin>>n;
int a[max];
memset(a,0,sizeof(a));//数组所有为初始化为0 
// 实现阶乘和存储
int jw=0,t=0;
a[0]=1;
//大数a乘以一个整数k变为将数组A的每一个元素都乘以k,请注意处理相应的进位。
for(int i=2;i<=n;i++) {//n的阶乘  n次循环 
	 for(int j=0;j<max;j++){//计算数组所有位的数字 
	 //例如 i=5时  5!=120  a[0]=0 a[1]=2 a[2]=1 a[3~max]=0 
	 	t=a[j]*i+jw;//第j位的阶乘结果 + 进位= 第j位最终结果 
	 	jw=t/10;// 第j位向高一位进位 
		a[j]=t%10; // 第j位的数字 
	 }
}
//逆序输出 需要处理数组高位未用到的0
int k;
  for(k=max-1;k>=0;k--) {//逆序寻找第一个不为0的位 
  	if(a[k]!=0) break;
  }
//逆序输出
  for(int g=k;g>=0;g--) {
  	cout<<a[g];
  }
  return 0;
}

核心算法理解

以5!为例

其他题目

问题描述
  输入两个整数a和b,输出这两个整数的和。a和b都不超过100位。
算法描述
  由于a和b都比较大,所以不能直接使用语言中的标准数据类型来存储。对于这种问题,一般使用数组来处理。
  定义一个数组A,A[0]用于存储a的个位,A[1]用于存储a的十位,依此类推。同样可以用一个数组B来存储b。
  计算c = a + b的时候,首先将A[0]与B[0]相加,如果有进位产生,则把进位(即和的十位数)存入r,把和的个位数存入C[0],即C[0]等于(A[0]+B[0])%10。然后计算A[1]与B[1]相加,这时还应将低位进上来的值r也加起来,即C[1]应该是A[1]、B[1]和r三个数的和.如果又有进位产生,则仍可将新的进位存入到r中,和的个位存到C[1]中。依此类推,即可求出C的所有位。
  最后将C输出即可。
输入格式
  输入包括两行,第一行为一个非负整数a,第二行为一个非负整数b。两个整数都不超过100位,两数的最高位都不是0。
输出格式
  输出一行,表示a + b的值。

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <algorithm> 
#include <string.h>
#define max 103
//本题难点在大数的输入 与 倒序存入数组 
using namespace std;
int main(){
char a[max],b[max];
scanf("%s",a);
scanf("%s",b);//数组a b 正序存入的两个大数 例如12223 1
int as[max],bs[max],c[max];//as bs 倒序存入的两个大数32221 1;c存最后结果 
memset(as,0,sizeof(as));
memset(bs,0,sizeof(bs));
memset(c,0,sizeof(c));
//字符数组a--》 整数数组as(倒序) ;字符数组b--》 整数数组bs(倒序) 
for(int i=0;i<strlen(a);i++){	
	as[i]=a[strlen(a)-i-1]-'0';//将字符数组a中元素变成整数 并 倒序存入as 
}
for(int j=0;j<strlen(b);j++){
	bs[j]=b[strlen(b)-j-1]-'0';
}
//加法过程 
int t=0,jw=0;
for(int k=0;k<max;k++){
	t=as[k]+bs[k]+jw;
	c[k]=t%10;
	jw=t/10;
} //32221 1结果为4222100000000000...
// 逆序输出数组c  需要处理数组高位未用到的0
int d;
for(d=max-1;d>=0;d--){
	if(c[d]!=0) break;
}
//逆序输出c 
for(int e=d;e>=0;e--){
	cout<<c[e];
}
return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值