大数加法-蓝桥杯

文章讲述了如何在C++中使用高精度算法进行大整数加法(1516题)和阶乘计算(1515题),包括字符串表示大数、处理进位、数组存储及模拟乘法运算的方法。
摘要由CSDN通过智能技术生成

lanqiaoOJ题号1516

【题⽬描述】输⼊两个整数a和b,输出这两个整数的和。a和b 都不超过100位。

本题和下⼀题介绍计算⼤数的乘法和加法。在C/C++中,⼤数的 计算⽅法称为⾼精度算法,是常⻅的考题。⽽使⽤Python和 Java代码能直接计算⼤数,不需要⽤⾼精度算法。

C++的数据类型中,最⼤的long long类型,可以声明64位的⼆ 进制数变量。此题的关键是处理⼤数的输⼊,因为整数a和b太 ⼤,⽆法将其直接赋值给C++的变量,所以不能按数字读⼊,只 能按字符读⼊。 ⼤数a⽤字符串来存储,⼀个字符存储⼀位数字,a[0]存最⾼位 数字,a[1]存次⾼位数字……a[n−1]存最低位数字,等等。计算a 加上b,先模拟每⼀位相加,再处理进位。

//1计算大整数加法
string bigint_add(string a,string b){//a,b数字字符串中的低位在前
    string s,st;
    int temp=0;//用来存储可能产生的进位
    for(int i=a.size()-1,j=b.size()-1;i>=0||j>=0||temp>0;i--,j--){//倒序遍历,注意这里temp不为0也要循环一次
        if(i>=0) temp+=a[i]-'0';
        if(j>=0) temp+=b[j]-'0';
        st=temp%10+'0';
        s=st+s;//新加入的高位放在 s 前面,保证输出不会反
        temp=temp/10;
    }
    // reverse(s.begin(),s.end());
    return s;
}

1利用循环条件巧妙的解决了相加的大整数长度不一样的情况,另外注意temp>0也需要进入循环。

2temp赋值之前要判断一下避免越界,结果字符串记得要倒序,s=st+s可以把新获得的数直接加在前面或者出循环后倒置一下s可以起到一样的效果

lanqiaoOJ题号1515

【题⽬描述】输⼊⼀个正整数n,输出n!的值,n≤1000。

C++代码。 阶乘的值极⼤,在C++中,unsigned long long类型变量的最⼤ 值是264,⽽21!就已经⼤于264了,所以需要⽤数组来存这个 ⼤数。

这是⼀道⾼精度算法题⽬,⾼精度算法可⽤数组实现。编 程时注意以下细节。

①定义⼀个数组a[]来存放⼤数,数组的⼀个元素存放⼤数的⼀ 位数字。例如a[0]存放个位数,a[1]存放⼗位数,a[2]存放百位 数,等等。

②数组a[]需要定义成多⼤?也就是说,1000!有多少位?可以⽤ Windows⾃带的计算器直接算出来,1000! ≈4×102567。代码中 简单地定义成⼀个更⼤的数组a[10000]。

③模拟乘法运算,处理进位。 例如356×8,先计算个位的6×8,得48,其中个位的8等于 48%10=8,进位的4等于48/10=4。⻅下⾯代码中的第10~第 13⾏,这⼏⾏代码实际上是处理了两个数的乘法,请仔细分析这 ⼏⾏代码。

④按③的计算⽅法计算n!。i遍历了1~n,计算 n!。

⑤从最⾼位开始输出。先找到最⾼位,即第⼀个不等于0的数, 然后从⾼位往最低位输出。 ✧ 提示:const int a[]表示定义⼀个⼤静态数组,⼤静态 数组应该定义在全局。如果将其定义在函数内部,有些编译器会 报错。 有的读者可能知道需要考虑代码的计算复杂度问题,共循环计算了 10000×n = 10000×1000 = 1千万次,不会超时。

const int N=10000;
int a[N]={0};//在全局定义了一个大静态数组
void pow_n(int n){
    a[0]=1;
    int temp=0;//用来存储可能产生的进位
    for(int i=1;i<=n;i++){//模拟阶乘计算
        for(int j=0;j<=N;j++){
            temp+=i*a[j];//以下三行实际处理了两个数的乘法
            a[j]=temp%10;
            temp=temp/10;
        }
    }
    int flag=0;
    for(int i=N-1;i>=0;i--){
        if(a[i]!=0){//找到第一个不为0的数,开始打印
            flag=i;
            break;
        }
    }
    for(int i=flag;i>=0;i--) cout<<a[i];
}

这里阶乘计算的核心在于可以直接把i和a[j]相乘,由于a是从低位到高位存储的,符合乘法的基本步骤,只要这里的结果没有超出范围,那总的结果就可以保证是对的。如果还是不清楚可以自己按照代码手算一下比较。

如144*96。那么a={441},i=96

1. 4*96=384, 4留下,temp=38

2. 4*96=384,(temp+4)%10=2,temp=(temp+4)/10=42

3.1*96=96,(temp+96)%10=8,temp=(temp+96)/10=13

由于循环从0-N-1且N足够大,保证temp可以在循环里两次赋值,留下3,1

最后倒序输出13824

验证:

1

    a="123456789123456789";
    b="12345678912345678912345";
    //结果是12345802369134802369134

2求100的阶乘

    //结果是93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雾渐起

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值