关于『基本算法』:高精度
建议缩放90%食用
在 C2024XSC717 小姐姐的再三恳求下,在下码了这篇模板。但确凿高精度这玩意儿实在是太太太……(此处省略10086字)常用了,十道题有三道用高精,还是高精加减乘除混着用的那种。。。((蒟蒻无语
高精度! No face! Every day!1
以下为在下编写的高精模板,有误请指出谢谢( ̄︶ ̄)↗ (蒟蒻大鸽子要掏出它的代码了!!1)
(奇怪的知识又增加了呢~)
基本算法向你发起进攻,请注意防守🔫🔫🔫
废话 is over.
a + b 真的等于 a + b 吗?
注:本篇主要集合了个人见解,在某些地方也许弥天大雾,敬请指出
正文 is begin.
高精度算法,属于处理大数字的数学计算方法
在一般的科学计算中,会经常算到小数点后几百位或者更多,当然也可能是几千亿几百亿的大数字
一般这类数字我们统称为 “高精度数” ,高精度算法是用计算机对于超大数据的一种模拟加,减,乘,除,乘方,阶乘,开方等运算
一、高精度加法 ( H i g h p r e c i s i o n a d d i t i o n ) (High\ precision\ addition) (High precision addition)
1.题目运用(#419. 简单高精度加法)
/*
#419. 简单高精度加法
题目描述:
计算两个非负整数A、B的和,其中A和B的位数在5000位左右。
输入格式:
共两行数据,第一行为一个非负整数A,第二行为一个非负整数B,A、B的位数均在5000以内。
输出格式:
输出一个非负数,即两数之和。
样例输入:
11111111111
22222222222
样例输出:
33333333333
*/
#include <cstdio>
#include <cstring>
const int M = 5e3 + 5;
char s1[M], s2[M];
int a[M], b[M], c[M];
int main() {
scanf("%s\n%s", s1, s2);
int l1 = strlen(s1), l2 = strlen(s2);
for (int i = 1; i <= l1; i++) { //因为加法涉及进位问题,比如99+3=102,这个1就是进位,在数组最后插入元素是很方便的,所以倒序存放
a[i] = s1[l1 - i] - '0';
}
for (int i = 1; i <= l2; i++) {
b[i] = s2[l2 - i] - '0';
}
//高精加算法部分
int l3 = 1, x = 0; //记录进位
while(l3 <= l1 || l3 <= l2) { //将两数所有位相加
c[l3] = a[l3] + b[l3] + x; //答案的这一位 等于 a数组的这一位 加上 b数组的这一位 再加上进位
x = c[l3] / 10; //记录进位
c[l3] %= 10; //进位后该位的值
l3++; //答案的长度加一
}
c[l3] = x; //答案的最高位是最后一次进位的数
while (c[l3] == 0 && l3 > 1) { //删除前导零
l3--;
}
for (int i = l3; i >= 1; i--) {
printf("%d", c[i]);
}
return 0;
}
3.习题演练
(1). 基础框架
- #419. 简单高精度加法
- #6365. 高精度加法
- #8119. 高精度加法
- #8487. 基础题十 高精度加法
(2). 实际运用
- #329. 铺砖2
- #411. 求n累加和
- #416. 被限制的加法
二、高精度减法 ( H i g h p r e c i s i o n s u b t r a c t i o n ) (High\ precision\ subtraction) (High precision subtraction)
1.题目运用(#420. 简单高精度减法)
/*
#420. 简单高精度减法
题目描述:
求出A-B的值,其中A和B均为非负整数,其位数不超过5000。
输入格式:
共两行数据,第一行为一个非负整数A,第二行为一个非负整数B,A、B的位数均在5000以内。
输出格式:
输出一个整数,即A-B的值。
样例输入:
2
1
样例输出:
1
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int M = 5e3 + 5;
char s1[M], s2[M];
int a[M], b[M], c[M];
int main() {
scanf("%s\n%s", s1, s2);
int l1 = strlen(s1), l2 = strlen(s2);
if (l1 < l2 || (l1 == l2 && strcmp(s1, s2) < 0)) { //判断被减数是否小于减数
printf("-"); //判定值为负
swap(s1, s2); //交换被减数和减数(使其转化为绝对值相减)
swap(l1, l2); //交换长度
}
for (int i = 1; i <= l1; i++) {
a[i] = s1[l1 - i] - '0';
}
for (int i = 1; i <= l2; i++) {
b[i] = s2[l2 - i] - '0';
}
//高精减算法部分
int l3 = 1, x = 0;
while (l3 <= l1 || l3 <= l2) {
if (a[l3] < b[l3]) { //不够减时借位
a[l3] += 10; //借一着十
a[l3 + 1]--; //被借位要退位
}
c[l3] = a[l3] - b[l3]; //数位相减
l3++;
}
while (c[l3] == 0 && l3 > 1) { //删除前导零
l3--;
}
for (int i = l3; i >= 1; i--) {
printf("%d", c[i]);
}
return 0;
}
2.习题
1.基础框架
- #420. 简单高精度减法
- #6364. 高精度减法
- #8120. 高精度减法
- #8488. 基础题十一 高精度减法
2.实际运用
- 暂未找到相关题目
三、高精度乘法 ( H i g h p r e c i s i o n m u l t i p l i c a t i o n ) (High\ precision\ multiplication) (High precision multiplication)
1.题目运用(#417. 简单高精度乘法)
/*
#417. 简单高精度乘法
题目描述:
铐住修罗王和邪狼的魔法手铐镌刻着两行数字,修罗王猜测其开启密码是这两行数字的乘积,为此他需要编写一
个简单高精度乘法的程序以验证其猜测。即已知A和B的值,其中A、B的位数不超过5000,试求出A×B的值。
输入格式:
为两行数字即A和B,A、B的倍数不超过5000位。
输出格式:
为一行数字,即A×B的值。
样例
样例输入
2
3
样例输出
6
*/
#include <cstdio>
#include <cstring>
char s1[5005], s2[5005];
int a[5005], b[5005], c[10005];
int main() {
scanf("%s\n%s", s1, s2);
int l1 = strlen(s1), l2 = strlen(s2);
for (int i = 1; i <= l1; i++) {
a[i] = s1[l1 - i] - '0';
}
for (int i = 1; i <= l2; i++) {
b[i] = s2[l2 - i] - '0';
}
//高精乘算法部分
for (int i = 1; i <= l1; i++) { //模拟手算过程
for (int j = 1; j <= l2; j++) {
c[i + j - 1] += a[i] * b[j];
c[i + j] += c[i + j - 1] / 10; //进位
c[i + j - 1] %= 10; //进位后该位的值
}
}
int l3 = l1 + l2; //积可能的最大的位数是两因数位数之和
while (c[l3] == 0 && l3 > 1) { //删除前导零
l3--;
}
for (int i = l3; i >= 1; i--) {
printf("%d", c[i]);
}
return 0;
}
2.习题演练
(1). 基础框架
- #417. 简单高精度乘法
- #6363. 高精度乘法
(2). 实际运用
- #359. 编程社买书
- #410. 求n的阶乘
- #412. 阶乘和
- #421. 高精度阶乘
- #422. 高精度幂
四、高精度除法 ( H i g h p r e c i s i o n D i v i s i o n ) (High\ precision\ Division) (High precision Division)
1.题目运用(#423. 高精度数除以低精度数1)
/*
#423. 高精度数除以低精度数1
题目描述:
输入一被除数(位数 <= 5000),输入一除数(整型数据范围内),输出整数商,忽略小数。
输入格式:
输入共两行,第一行为一个数字字符串,即被除数,第二行为一个整数,即除数。
输出格式:
输出整数商,忽略小数。
样例
样例输入
20
5
样例输出
4
*/
#include <cstdio>
#include <cstring>
char s1[5005];
int a[5005], b, c[5005];
int main() {
scanf("%s\n%d", s1, &b);
int l1 = strlen(s1);
for (int i = 1; i <= l1; i++) {
a[i] = s1[i - 1] - '0';
}
//高精除算法部分
long long x = 0; //记录余数
for (int i = 1; i <= l1; i++) {
c[i] = (a[i] + 10 * x) / b; //计算本步的商
x = (a[i] + 10 * x) % b; //记录余数
}
int begin = 1; //除法从开头去前导零
while (c[begin] == 0 && begin < l1) {
begin++;
}
for (int i = begin; i <= l1; i++) {
printf("%d", c[i]);
}
return 0;
}
2.习题演练
(1). 基础框架
- #424. 高精度数除以低精度数2
- #6362. 高精除低精
- #9034. 「基础算法」高精度除法
(2). 实际运用
- 暂未找到相关题目
填上一个坑辣~🎉🎉🎉
年度总结持续中。。。
关于『基本算法』:高精度 完结啦撒花 []( ̄▽ ̄)🌸 (好久没撒花了)
(翻以前的稿发现我原来咕咕了一个如此久远的坑, hh…)