洛谷 P1480 A/B Problem(高精度详解)c++
题目链接:P1480 A/B Problem - 洛谷
1.题目分析
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;
}