计蒜客 T1100:计算2的N次方(高精度乘法详解)

上一篇博客:计蒜客 T1099:大整数减法(高精度减法详解)java

 写在前面:你们好!我是ACfun,个人昵称来自两个单词Acceptedfun。我是一个热爱ACM的蒟蒻。这篇博客来说解一下高精度问题中的乘法。若是博客中有不足或者的错误的地方欢迎在评论区或者私信我指正,感谢你们的不吝赐教。个人惟一博客更新地址是:https://ac-fun.blog.csdn.net/。很是感谢你们的支持。一块儿加油,冲鸭!
用知识改变命运,用知识成就将来!加油 (ง •̀o•́)ง (ง •̀o•́)งios

题目信息

原题链接:计算2的N次方web

题目描述

 任意给定一个正整数 N (N≤100),计算 2 的 N 次方的值。算法

输入格式

 输入一个正整数 N。数组

输出格式

 输出 2 的 N 次方的值。svg

提示

 高精度计算。测试

 输出时每行末尾的多余空格,不影响答案正确性spa

样例输入

5.net

样例输出

32code

题解

解题思路

使用两个 vector 数组 mul 和 ans 来分别存储 上一次乘以二的结果 和 下一次乘以二 的结果首先把 1 放到mul 数组中,而后进行乘以 2 ,将得出的结果 2 存储到 ans数组中;而后咱们将 mul 数组清空,再将上一次乘以 2 的结果存储到 mul 中,而后将 ans 清空来继续下一次循环,从新存储下一次乘以 2 的结果。不断的循环这一步骤直到循环 N 次,即求出 2^N 的结果。最终倒着输出便可。这里关于相乘的具体解释放到后面的高精度乘法详解讲述。先看一下 AC 的代码。

解题代码

#include<iostream>
#include<vector>
using namespace std;

int main() {
    int n;
    vector<int> ans, mul;
    cin >> n;
    mul.push_back(1);
    
    for (int i = 0; i < n; i++) {
        int len = mul.size();
        for (int i = 0, t = 0; i < len || t; i++) {
            if (i < len) t += mul[i] * 2;
            ans.push_back(t % 10);
            t /= 10;
        }
        
        mul.clear();
        
        int len_ans = ans.size();
        for (int k = 0; k < len_ans; k++) mul.push_back(ans[k]);

        ans.clear();
    }
    
    int len = mul.size();
    for (int i = len - 1; i >= 0; i--) printf("%d", mul[i]);
    
    return 0;
}

高精度乘法详解

高精度算法简介

 高精度算法简介已经在以前的博客 计蒜客T1098:大整数加法(高精度加法详解) 中详细的介绍过了,这里就再也不赘述了。

大数的存储方式

 大数的存储方式也在以前的博客 计蒜客T1098:大整数加法(高精度加法详解) 中详细的介绍过了,这里也再也不赘述了。这里主要介绍一下高精度乘法的实现方式。

高精度乘法实现

这里主要介绍一下一个大整数 A 乘以一个比较小的数 b 的实现方法,两个大整数相乘的实现方法是同样的,不一样之处在于两个大数相乘须要将第二个数也拆开分别进行相乘。首先咱们定义一个vector数组 ans 来存储相乘以后的结果,定义一个整型变量 t 来存储每次的进位的值。由于是倒着存储的大数,因此在相乘的时候咱们从下标为 0 的数字开始相乘依次向后遍历,而且将每次的相应数位相乘的结果放到数组 ans 中。
 每次相乘以前咱们都须要先判断一下数组是否越界了,若是没有越界就使 t 加上当前位乘以较小的数字 b(注意:由于第二个数字 b 比较小,因此咱们直接使 A[i] * b,即大数 A 的每一位数字 直接与 b 相乘,而不须要将 b 拆开,由于 b 比较小,因此咱们不须要像大数 A 那样将 A 的每一位拆开进行相乘。 )。而后将 t % 10 即结果的个位放在当前位置上,而后使 t /= 10 算出进位的值,在下一次循环直接加上该进位的值便可。重复进行这一操做直到将数组 A 中的全部数位乘完,而且检查一下 t 是否进完位,若是相乘结束以后 t 不为 0 ,说明最后一个数位与 b 相乘仍是须要进位,那么就继续执行 t % 10,t /= 10 的操做,直到 t = 0为止。
最后须要注意去除结果中的前导零。由于测试样例中可能会有 A * 0 的状况,若是不去除前导零会出错。

高精度乘法模板

vector<int> mul(vector<int> &A, int b) {
    vector<int> ans;
    int len = A.size();
    int t = 0;
    for (int i = 0; i < len || t; i++) {
        if (i < len) t += A[i] * b;
        ans.push_back(t % 10);
        t /= 10;
    }
    // 去除结果中的前导零
    while (ans.size() > 1 && ans.back() == 0) ans.pop_back();
    
    return ans;
}

高精度乘法完整模板

模板题目连接:高精度乘法

#include<iostream>
#include<vector>
using namespace std;

vector<int> mul(vector<int> &A, int b) {
    vector<int> ans;
    int len = A.size();
    int t = 0;
    for (int i = 0; i < len || t; i++) {
        if (i < len) t += A[i] * b;
        ans.push_back(t % 10);
        t /= 10;
    }
    // 去除结果中的前导零
    while (ans.size() > 1 && ans.back() == 0) ans.pop_back();
    
    return ans;
}

int main() {
    string a;
    int b;
    cin >> a >> b;
    vector<int> A;
    
    int len = a.size();
    for (int i = len - 1; i >= 0; i--) A.push_back(a[i] - '0');
    
    vector<int> ans = mul(A, b);
    
    int len_ans = ans.size() - 1;
    for (int i = len_ans; i >=0; i--) printf("%d", ans[i]);
    
    return 0;
}

我是ACfun,感谢你们的支持!
喝杯java冷静一下