题目如下

对于32位字长的机器,大约超过20亿,用int类型就无法表示了,我们可以选择int64类型,但无论怎样扩展,固定的整数类型总是有表达的极限!如果对超级大整数进行精确运算呢?一个简单的办法是:仅仅使用现有类型,但是把大整数的运算化解为若干小整数的运算,即所谓:“分块法”。


上图表示了分块乘法的原理。可以把大数分成多段(此处为2段)小数,然后用小数的多次运算组合表示一个大数。可以根据int的承载能力规定小块的大小,比如要把int分成2段,则小块可取10000为上限值。注意,小块在进行纵向累加后,需要进行进位校正。

请从以下四个选项中选择正确答案,填补在空白处,使得代码能运行后能产生正确的结果。

最终代码如下

#include <bits/stdc++.h>
using namespace std;void bigmul(int x, int y, int r[])
{int base = 10000;int x2 = x / base;int x1 = x % base;int y2 = y / base;int y1 = y % base;int n1 = x1 * y1;int n2 = x1 * y2;int n3 = x2 * y1;int n4 = x2 * y2;r[3] = n1 % base;r[2] = n1 / base + n2 % base + n3 % base;r[1] = n2 / base + n3 / base + n4 % base;r[0] = n4 / base;r[1] += r[2] / base;r[2] = r[2] % base;r[0] += r[1] / base;r[1] = r[1] % base;
}int main(int argc, char *argv[])
{int x[] = {0, 0, 0, 0};bigmul(87654321, 12345678, x);printf("%d%d%d%d\n", x[0], x[1], x[2], x[3]);return 0;
}

这次的练习相对偏中等难度,其实很多时候,都是理念问题,思路对了解起来就容易。下面上解析。

解题思路

1. 获取x1,x2,y1,y2

    int base = 10000;int x2 = x / base;int x1 = x % base;int y2 = y / base;int y1 = y % base;

这里有个大前提啊同学们,输入的整数x和y必须是大整数,10000以上的吧,要不然没有意义。

正常我们是十进制,这里按照10000进制,将大整数拆分成两个小一点的整数。

2.计算x1*y1,x1*y1,x2*y1,x2*y2的值

    int n1 = x1 * y1;int n2 = x1 * y2;int n3 = x2 * y1;int n4 = x2 * y2;

分别是n1,n2,n3,n4,从上到下。

3.竖列相加

    r[3] = n1 % base;r[2] = n1 / base + n2 % base + n3 % base;r[1] = n2 / base + n3 / base + n4 % base;r[0] = n4 / base;

题目中是r1~r4,但是我们数组中是从0开始的,所以是r0~r3,大家知道怎么回事就行,别自己搞乱了。备注:特别容易搞乱,注意r1和r[1],带不带方括号很重要,r1=r[0].

这里的数字采用数组进行存储:

看图可知,r4=r[3]是n1后面一位,按照咱们认为的10000进制,那么r[3]=n1 % base,就是个整除取余。

看图可知,r3=r[2]是n1前一位加上n2和n3的后一位,那么r[2]=n1 / base + n2 % base + n3 % base。

看图可知,r2=r[1]是n2和n3的前一位加上n4后一位,那么r[2]=n2 / base + n3 / base + n4 % base。

看图可知,r1=r[0]是n4的前一位,那么r[0]=n4 / base。

4.进位

    r[1] += r[2] / base;r[2] = r[2] % base;r[0] += r[1] / base;r[1] = r[1] % base;

还是把这个图拿过来了,方便看,另外,先不要看上面的代码,先看博主分析:

r4=r[3]就不说了,m1本身就是n1 % base之后的值,不需要进位。

r3=r[2]不知道要不要进位,所以需要整除取余,不需要进位,就是本身,需要进位,取余之后的值就是r3,即r[2].

r2 = r[1]也不知道要不要进位,算就完了,所以r[1] = r[1] + r[2] / base。我们就假设r3要进位,那就要加上进位的数,r3 / base就是这个数,有的话就是个大于0的值,没有的话就是0。

r1 = r[0]也不知道要不要进位,同样的,算就完了,和上面的一样,r[0]=r[0]+r[1]/base。都是先假设r2有进位,加上进位的数,r2 / base就是这个数,有的话就是个大于0的值,没有的话就是0。

最后你发现代码和上面的不一样,对不对?那就对了,需要注意什么呢?

r[1] = r[1] + r[2] / base之后,r[1]是不是也有进位的可能,所以r[1]要接着取余,r[1] = r[1] % base。

r[0]已经是第一位了,没有取余的必要了,现在,代码和上面的一样了。

5.最终运算

在main函数中调用bigmul,传入参数,然后直接按顺序不换行输出x[0], x[1], x[2], x[3],连起来就是两个大整数想成的积。

总结

再次感叹数学的伟大,大学时高数里可也是没有学过这样的公式运算,抑或是学过我忘了?真是没有一点印象,有句话叫:世上的一切问题都可以用数学解决。真是越看越心惊,我这里写完了,不知道大家都看懂没,欢迎评论区留言讨论。

蓝桥杯练习题六 - 大数乘法(c++)相关推荐

  1. 蓝桥杯第六届决赛真题大全解(java版本)

    文章推荐 精选java等全套学习资源 精选java电子图书资源 精选大数据学习资源 java项目练习精选 >蓝桥杯第六届决赛第一题[(详情(分机号))](http://blog.csdn.net ...

  2. 蓝桥杯练习题Java实现 入门训练 Fibonacci数列

    蓝桥杯练习题Java实现 入门训练 Fibonacci数列 问题描述 Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1. 当n比较大时,Fn也非常大,现在我们想知道,F ...

  3. 【蓝桥杯第六届省赛题-简易温度采集与控制装置】

    蓝桥杯第六届省赛题-简易温度采集与控制装置 #include "reg52.h" #include "onewire.h" #include "int ...

  4. 蓝桥杯练习题 回文数

    蓝桥杯练习题 回文数 问题描述 1221是一个非常特殊的数,它从左边读和从右边读是一样的,编程求所有这样的四位十进制数. 输出格式 按从小到大的顺序输出满足条件的四位十进制数. #include< ...

  5. 蓝桥杯练习题十一 - 乘积尾零(c++)

    题目如下 如下的10行数据,每行有10个整数,请你求出它们的乘积的末尾有多少个零? 5650 4542 3554 473 946 4114 3871 9073 90 4329 2758 7949 61 ...

  6. c语言六角填数蓝桥杯答案,六角填数(全排列)蓝桥杯真题

    六角填数(全排列)蓝桥杯真题 六角填数(全排列)蓝桥杯真题 如图所示六角形中填入1-12的数字,使每条直线上的数字和相等,图中已经填好了3个数字,请你计算*号数字是多少 蓝桥杯老套路,经常这样考全排列 ...

  7. Java 01背包【动态规划·蓝桥杯练习题】(相信杨超越,相信锦鲤,默默努力,其它的看天意)

    锦鲤镇楼 1.题目描述: 时间限制:1.0s 内存限制:256.0MB 关键字:01背包 动态规划 问题描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间他自己专用的很宽敞的房间.更让他高 ...

  8. 蓝桥杯第六届国赛JAVA真题----切开字符串

    标题:切开字符串 Pear有一个字符串,不过他希望把它切成两段. 这是一个长度为N(<=10^5)的字符串. Pear希望选择一个位置,把字符串不重复不遗漏地切成两段,长度分别是t和N-t(这两 ...

  9. 蓝桥杯练习题 Fibonacci数列

    下学期要跟着学校去参加蓝桥杯,所以在这里自己留念之用.(java) 1 Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1. import java.util.Scann ...

最新文章

  1. NLP实践:对话系统技术原理和应用
  2. 使用Fiddler解析WCF RIA Service传输的数据
  3. attribute java c_属性别名(Attribute Aliasing)
  4. 简述MVC思想与PHP如何实现MVC
  5. MySQL_JDBC_数据库连接池
  6. php $db-gt;query 行数,php – 如何在CodeIgniter中组合query()和limit()方法
  7. 大数据面试-03-大数据工程师面试题
  8. 及时复盘的好处_如何做好2020的年终复盘?
  9. cnn 回归 坐标 特征图_论文笔记 | CNN 是怎么学到图片绝对位置信息的
  10. python直接取系统的时间_用Python在Linux中获得系统正常运行时间的最快方法
  11. [转]程序员资料整理
  12. 爱普生690k打印针测试软件_针式打印机断针测试软件_9针、24针打印机断针测试 V1.3 下载...
  13. 投影机拼接融合技术--UE4拼接
  14. ios kb转m_字节、kb、M怎么换算
  15. oracle中的删除与数据库中的回收站
  16. 2017年全球IDC、光器件、100G及400G数通模块市场预测
  17. Tikhonov正则化方法在测绘领域的综述
  18. XML(1)——shema约束之命名空间
  19. proc*c/c++简介
  20. python高频面试题_02-27 朴素贝叶斯

热门文章

  1. python指数、幂数拟合curve_fit
  2. JavaScript-84:利用函数求任意两个数的和
  3. CSS(Cascading Style Sheets) 层叠样式表
  4. 山东省省外院校毕业生注册【山东省高校毕业生就业信息网】须知
  5. 初二数学作业能用计算机算吗,数学作业用计算器来计算,这种做法对吗?
  6. 蓝桥杯 算法训练 JAM计数法
  7. 【windows】SCCM部署系统时遇到的错误
  8. 数组以及字符串的常用方法
  9. 网页引入腾讯视频小记
  10. C++语法学习笔记二十七: 引用折叠,转发、完美转发,forward