题目链接:P1480 A/B Problem - 洛谷

1.题目分析

1:说明这里是高精度除以低精度的形式,为什么不是高精度除以高精度的形式,是因为它很少见,它的模拟方式是用高精度减法来做的,并不能用小学列竖式的方法模拟出来,但是如果用高精度除低精度的话,是可以用小学的方式模拟出来的,并且是有可能遇到,所以我们这里只了解高精度除以低精度就可以,至于高精度除高精度,大家感兴趣可以在网上搜一下

2.算法原理

解法:模拟列竖式计算的过程

  1. 用字符串读入第一个数,拆分每一位,逆序放在数组中
  2. 利用数组,模拟列竖式除法的过程

模拟一下小学列竖式除法过程,比如1234除4最高位是1,1/45是除不尽的,因此商0,0×45=0,1-0=1,拿余数1和后面的2拼接起来,如何落实到代码,可以创建一个变量t来记录余数1,再让t×10+2就变成12了,接下来用12/45的时候依旧是商0余12,把它拼接成123的步骤和刚刚一样,让12×10+3变成123,接下来拿123/45,2×45=90,123-90=33,如何拿到商2和余数90呢?当前的t=123,除45就可以拿到2,模45就可以拿到33,所以计算过程就是一直在重复t乘10加当前数、除除数、模除数、的步骤,继续向后进行预算就可以了

有可能余数会超过int范围,因为b的范围是是1e9级别的数,让它乘10会变成1e10,会超过整型范围,所以使用long long来存储

代码:

#include <iostream>
using namespace std;

const int N = 1e6 + 10;
typedef long long LL;

int a[N], b, c[N]; //被除数、除数、结果
int la, lc;

// 高精度除法的模板 - c = a / b (高精度 / 低精度)
void sub(int c[], int a[], int b)
{
    LL t = 0; // 标记每次除完之后的余数
    //除的时候是拿最高位试除的
    for (int i = la - 1; i >= 0; i--)
    {
        // 计算当前的被除数
        t = t * 10 + a[i]; //拼接被除数 12*10+3=123
        c[i] = t / b;      //拿商    123/45=2
        t %= b;            //取余数  123%45=33
    }

    // 处理前导 0
    while (lc > 1 && c[lc - 1] == 0) lc--;
}

int main()
{
    string x; cin >> x >> b;
    la = x.size();

    for (int i = 0; i < la; i++) a[la - 1 - i] = x[i] - '0';

    // 模拟除法的过程
    lc = la;
    sub(c, a, b); // c = a / b

    for (int i = lc - 1; i >= 0; i--) cout << c[i];

    return 0;
}
Logo

集算法之大成!助力oier实现梦想!

更多推荐