洛谷题单指南-模拟和高精度-P1303 A*B Problem

原题链接:https://www.luogu.com.cn/problem/P1303

题意解读:本题是高精度乘法的模版题。

知识点解析:

  高精度乘法:

  与高精度加法类似,需要用数组来存储数字的每一位,然后通过数组逐位的运算来模拟乘法的过程。

  这里有几个关键问题:

  1、整数的存储

  同高精度加法,参考高精度加法模版题

  2、乘法操作

  回归乘法的本质,以123 * 45为例,看乘法竖式:

    1 2 3

  ×  4 5

      ------

          1 5      计算5 * 3

    1 0        计算5 * 2

    5          计算5 * 1

    1 2    计算4 * 3        

    8          计算4 * 2

  4        计算4 * 1

    ------

    5 5 3 5

  从以上示例总结乘法运算的过程:

  设被乘数a,乘数b,a、b都是数组,下标0表示个位,令设结果数组c

  第一步:从b的个位开始(b的下标j从0->b.size()-1),依次与a的每一位做乘法运算(a的下标i从0->a.size()-1) ,

  第二步:运算结果存入c[i + j]

  第三步:进位存入c[i + j + 1] 

  编程中,要考虑当前运算结果和上次进位累加, 每次进位也要考虑和其他计算的数值累加,因此

  c[i + j] += a[i] * b[j];

  c[i + j + 1] += c[i + j] / 10;

  c[i + j] = c[i + j] % 10;

  第四步:由于乘法运算结果数组需要提前设定长度,最长为a、b数组长度之和,如10 * 10 = 100,结果需要3位数字,

  99 * 99 = 9801,结果需要4位数字,这样就导致结果数组的高位有可能存在多余的0,称为前导0,需要去除。

100分代码:

#include <bits/stdc++.h>
using namespace std;

vector<int> mul(vector<int> a, vector<int> b)
{
    vector<int> res(a.size() + b.size()); // 预设结果数组长度,便于后续赋值
    for(int i = 0; i < a.size(); i++)
    {
        for(int j = 0; j < b.size(); j++)
        {
            res[i + j] += a[i] * b[j];
            res[i + j + 1] += res[i + j] / 10;
            res[i + j] = res[i + j] % 10;
        }
    }
    //去前导0,如果res长度大于1且最后一个数字(对应高位)是0,则删除最后一个数字
    while(res.size() > 1 && res.back() == 0) res.pop_back(); 
    return res;
}

int main()
{
    string a, b;
    vector<int> aa, bb;

    cin >> a >> b;
    for(int i = a.size() - 1; i >= 0; i--) aa.push_back(a[i] - '0');
    for(int i = b.size() - 1; i >= 0; i--) bb.push_back(b[i] - '0');

    vector<int> result = mul(aa, bb);

    for(int i = result.size() - 1; i >= 0; i--) cout << result[i];
    
    return 0;
}

 

posted @ 2024-01-18 09:51  五月江城  阅读(47)  评论(0编辑  收藏  举报