蓝桥杯备战(AcWing算法基础课)-高精度-除-低精度

目录

前言

[1 题目描述](#1 题目描述)

[2 分析](#2 分析)

[2.1 关键代码](#2.1 关键代码)

[2.2 关键代码分析](#2.2 关键代码分析)

[3 代码](#3 代码)


前言

详细的代码里面有自己的部分理解注释

1 题目描述

给定两个非负整数(不含前导 00) A,B,请你计算 A/B 的商和余数。

输入格式

共两行,第一行包含整数 A,第二行包含整数 B。

输出格式

共两行,第一行输出所求的商,第二行输出所求余数。

数据范围

1≤A的长度≤100000,

1≤B≤10000,

B 一定不为 0

输入样例:

cpp 复制代码
123
9

输出样例:

cpp 复制代码
13
6

2 分析

这个题目B的值比较小,可以用高精度-除-低精度即可,和之前写的高精度-乘-低精度较为相似,它的运算过程和我们平常计算除法也是类似的

2.1 关键代码

cpp 复制代码
//A / b , C 是商,r 是余数 
vint div1(vint &A,LL b, LL &r) {
	vint C;
	r = 0;
	
	for(int i = A.size() - 1; i >= 0; i -- ) {
		//相当于
		//  i  2 1 0
		//     0 1 3
		//     _____ 
		//  9 /1 2 3
		//     0
		//     -----
		//     1 2
		//       9
		//     -----
		//       3 3
		//       2 7
		//     -----
		//         6
		//  初始余数 r0 = 0
		//  (r0 * 10 + A2) / 9 = (0 * 10 + 1) / 9 = 0 ,商为 0 ,余数 r1 = 1
		//  (r1 * 10 + A1) / 9 = (1 * 10 + 2) / 9 = 1 ,商为 1 ,余数 r2 = 3
		//  (r2 * 10 + A0) / 9 = (3 * 10 + 3) / 9 = 3 ,商为 3 ,余数 r1 = 6
		//  C = [0,1,3] ,注意是高位在数组低位 
		r = r * 10 + A[i];
		C.push_back(r / b);
		r  = r % b;
	}
	
	//因为 C = [0,1,3] 因为数值的高位在数组低位 ,要保证统一,需要反转 
	reverse(C.begin(),C.end());
	
	//反转之后,会出现前导0 
	while(C.size() > 1 && C.back() == 0) C.pop_back();

	return C;
}

2.2 关键代码分析

和我们正常的计算类似,不过为了方便存储,我们的商C先用下标低位存放数值高位,然后最后逆转就可以了。余数r就是r%b,至于r的计算,我们可以看123/9,按我们平常的除法运算,第一次肯定我们知道1/9肯定不够,所以直接在2的上面商个1,然后余数r=3,但是计算机不能像人那样可以看几步,所以我们必须先从1/9开始,也就是,r=r*10+A[i]=0*10+1=1(刚开始r=0)商C=r/b=1/9=0;第二次,r=r*10+A[i]=1*10+2=12(这其实就是我们平常下移一个数的意思,只不过我们默认权重变大了)商C=r/b=12/9=1,r=r%b=3;第三次r=r*10+A[i]=3*10+3=3,商C=r/b=33/9=3,r=r%b=6,循环结束。最后C=[0,1,3],需要反转并且去掉前导0,r=6

3 代码

cpp 复制代码
#include<iostream>
#include<vector>
#include<algorithm> 

using namespace std;
typedef long long LL;
typedef vector<int> vint;

const int N = 1e5 + 10;

//A / b , C 是商,r 是余数 
vint div1(vint &A,LL b, LL &r) {
	vint C;
	r = 0;
	
	for(int i = A.size() - 1; i >= 0; i -- ) {
		//相当于
		//  i  2 1 0
		//     0 1 3
		//     _____ 
		//  9 /1 2 3
		//     0
		//     -----
		//     1 2
		//       9
		//     -----
		//       3 3
		//       2 7
		//     -----
		//         6
		//  初始余数 r0 = 0
		//  (r0 * 10 + A2) / 9 = (0 * 10 + 1) / 9 = 0 ,商为 0 ,余数 r1 = 1
		//  (r1 * 10 + A1) / 9 = (1 * 10 + 2) / 9 = 1 ,商为 1 ,余数 r2 = 3
		//  (r2 * 10 + A0) / 9 = (3 * 10 + 3) / 9 = 3 ,商为 3 ,余数 r1 = 6
		//  C = [0,1,3] ,注意是高位在数组低位 
		r = r * 10 + A[i];
		C.push_back(r / b);
		r  = r % b;
	}
	
	//因为 C = [0,1,3] 因为数值的高位在数组低位 ,要保证统一,需要反转 
	reverse(C.begin(),C.end());
	
	//反转之后,会出现前导0 
	while(C.size() > 1 && C.back() == 0) C.pop_back();

	return C;
}

int main() {
	string a;
	LL b;
	cin>>a>>b;//a = "123",b = 12
	vint A;
	//A=[6 , 5 , 4 , 3 , 2 , 1],因为可能需要进位,个位放数组低位方便在数组高位加上进位
	for(int i = a.size() - 1 ; i >= 0 ; i --) {
		A.push_back(a[i] - '0');
	}

	if(b == 0) {
		cout<<"error";
	} else {
		LL r;
		vint C = div1(A,b,r);

		for(int i = C.size() - 1 ; i >= 0 ; i --) {
			cout<<C[i];
		}
		cout<<"\n"<<r;
	}

	return 0;
}
相关推荐
我也不曾来过15 分钟前
list底层原理
数据结构·c++·list
梁下轻语的秋缘1 小时前
每日c/c++题 备战蓝桥杯 ([洛谷 P1226] 快速幂求模题解)
c++·算法·蓝桥杯
CODE_RabbitV1 小时前
【深度强化学习 DRL 快速实践】逆向强化学习算法 (IRL)
算法
mit6.8242 小时前
[贪心_7] 最优除法 | 跳跃游戏 II | 加油站
数据结构·算法·leetcode
keep intensify2 小时前
通讯录完善版本(详细讲解+源码)
c语言·开发语言·数据结构·算法
shix .2 小时前
2025年PTA天梯赛正式赛 | 算法竞赛,题目详解
数据结构·算法
风铃儿~2 小时前
Java面试高频问题(26-28)
java·算法·面试
wuqingshun3141592 小时前
蓝桥杯 4. 卡片换位
算法·职场和发展·蓝桥杯
江沉晚呤时2 小时前
深入了解C# List集合及两种常见排序算法:插入排序与堆排序
windows·sql·算法·oracle·c#·排序算法·mybatis
egoist20232 小时前
【C++指南】告别C字符串陷阱:如何实现封装string?
开发语言·数据结构·c++·c++11·string·auto·深/浅拷贝