算法设计与分析:大整数的加减乘除运算

第1关:大整数的加减乘除运算

任务描述
本关任务:掌握大整数的基本思想,并运用大整数的基本运算计算出常规整数n的阶乘,然后统计大整数n!中数字0的个数。

相关知识
为了完成本关任务,你需要掌握:1.大整数的思想,2.大整数加法,3.大整数减法,4.大整数与整数的乘法,5.大整数乘法,6.大整数与整数的除法,7.n的阶乘求解思路。

大整数的思想
大整数的思想:用数组存储大整数(超长整数),为处理简单起见约定每个数组元素存放相同位数(T位)的数字片段(假定T=4位)。

设定一个大小为N的整型数组a[0,1,..,N−1],给定一个大整数998877665544332211,每个数组单元使用T=4位存储,为了方便计算,将大整数的低位存入数组的高维索引,如下图所示:

在代码文件里,char_to_int函数已经实现了大整数的字符串序列s到整型数组c的转化,c初始化全为0,然后从下标(N−1)开始从右至左存储大整数,每个数组单元存储T=4位数字,相对应在进制K=10 
T
 =10000的结果。

另外,output函数已经实现了整数数组的输出,基本思想是从左到右,遇到第一个不为0的数组单元为大整数的头,之后每个数组单元都输出T=4位数字(注意补0)。

大整数加法
大整数的加法和一般的整数加法是类似的,从低位开始,同位置的数相加,若大于进制K=10000,则进位,以此类推。特别的,当进制K=10时,每个数组单元存储的数字为T=1位,大整数的加法运算就等价于常规整数的加法运算,只不过是用数组来模拟计算过程。

例如两个大整数分别为998877665544332211和112233445566778899,按照T=4,K=10000的参数设定,分别存储在整型数组a和b中,数组大小都是N,它们的加法运算(c=a+b)过程如图所示:

大整数减法
同样的,大整数的减法过程与一般的整数减法也是类似的,从低位开始,同位置的数相减,被减数小于减数时,被减数向高位借1,当T=4,K=10000时,借一位相当于加10000。特别的,倘若被减大整数小于减数大整数,则先交换它们,然后再做减法,最后为结果添加负号,为了方便起见,本关卡的测试数据保证被减数大于减数。

对于上面的大整数a=998877665544332211和大整数b=112233445566778899,它们的减法运算(c=a−b)过程如下图所示:

大整数与整数的乘法
我们知道整数之间的乘法是逐位相乘,然后相加。对于大整数与整数之间的乘法,则是把“位”扩展成了“块”,即大整数的每个数组单元分别与整数相乘,然后加上进位(初始为0),并把结果放在对应位置上,若超过了进制K,则进位,以此类推。

例如大整数123456789和整数12345,按照T=4,K=10000的参数设定,大整数存储在整型数组d中,数组大小为N,整数存储在整型变量p中,它们的乘法运算(c=d×p)过程如图所示:

大整数乘法
我们已经知道了大整数与整数之间的乘法运算,对于大整数a与大整数b的乘法运算则是大整数与整数乘法运算的拓展,也就是说,将大整数a分别与大整数b的每个数组单元相乘,然后放置在相应位置上,并累加进位。

对于上面的大整数a=998877665544332211和大整数b=112233445566778899,它们的乘法运算(c=a×b)过程如下图所示:

大整数与整数的除法
大整数d与整数p的除法运算保留商和余数,其中商仍然可能是大整数,而余数则是比除数要小的整数。大整数作为被除数,从高位开始,依次(从左到右i=0→N−1)将每个数组单元d[i]除以除数p,当前整除结果作为商存储在数组c对应的高位c[i]中,余数保留到下一个数组单元的计算中,依次类推,最后的余数则是大整数被除尽后的剩余项。

对于上面的大整数d=123456789和整数p=12345,它们的除法运算(c=d/p,r=d过程如下图所示:

n的阶乘求解思路
n的阶乘是一个非常大的整数,首先需要运用大整数的基本运算法则求得n!的数值。这一步可以借助大整数与整数的乘法运算,然后循环n−1次乘法即可得到n!。

n!=1×2×3×..×n

其次是统计n!中数字0的个数,因为大整数在数组中是分块存储的,所以有两种统计方式(记n!=M):

借助大整数与整数的除法运算:让M除以10,判断余数r是否为0,若为r=0,则答案累加1,然后将M赋值为商c,即M=c,重复以上步骤,直到M=0,程序结束;

借助大整数在数组中的分块存储方式:循环枚举大整数n!的数组单元,计算每个单元里的整数包含数字0的个数,最后进行累加求和即为答案。注意,每个整数单元里的数值不一定为T=4位,比如M[i]=102,当i不是大整数的头时,M[i]的真实数据为0102,包含两个数字0(一个简单的处理技巧:将M[i]加上K=10000,即M[i]+K=10102,然后判断它所包含的数字0的个数)。

编程要求
本关的编程任务是补全右侧代码片段calc中Begin至End中间的代码,具体要求如下:

在calc中,根据大整数的基本运算原理,计算整数n的阶乘,并统计出n!中数字0的个数,然后将统计结果作为函数返回值。
测试说明
平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确,测试数据保证10001>n>0。

以下是平台的测试样例:

测试输入:
10
预期输出:
 2

输入格式:
第1行:整数n
输出格式:
第1行:n!中数字0的个数

Tips:注意整数乘法越界的情况

开始你的任务吧,祝你成功!

//
//  main.cpp
//  step1
//
//  Created by ljpc on 2018/12/4.
//  Copyright © 2018年 ljpc. All rights reserved.
//#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>using namespace std;// 最大长度N,分块长度K
const int N = 10001;
const int K = 10000;
const int T = (int)log10(K); // K=10000, T=4void char_to_int(char *s, int *c)
{// *s = 1234567890// *c = 0000 .... 0012 3456 7890 (K=10000, T=4, c[0] c[1] .... c[N-2] c[N-1])// i  = 0         N-3  N-2  N-1  (c的下标索引i)int L = (int)strlen(s);for (int i=N-1; i>=0; i--) {c[i] = 0;if (L>=0) {for (int j=0; j<T; j++) {if (L-T+j < 0) {continue;}c[i] = c[i] * 10 + s[L-T+j] - '0';}L -= T;}}
}void output(int *c)
{// *c = 0000 .... 0012 3456 7890 (K=10000, T=4, c[0] c[1] .... c[N-2] c[N-1])// i  = 0         N-3  N-2  N-1  (c的下标索引i)// out= 1234567890bool flag = true;for (int i=0; i<N; i++) {if (flag && c[i]==0) {continue;}if (flag) { // 第一个非0数字:大数的头块printf("%d", c[i]);flag = false;}else { // 大数头块之后的 T 数字块int TK = K/10;int tmp = c[i];while (TK) {printf("%d", tmp/TK);tmp %= TK;TK /= 10;}}}printf("\n");
}void add(int *a, int *b, int *c)
{int carry = 0;for (int i=N-1; i>=0; i--) {c[i] = 0;c[i] = a[i] + b[i] + carry;carry = c[i] / K;c[i] = c[i] % K;}}void sub(int *a, int *b, int *c)
{int borrow = 0;for (int i=N-1; i>=0; i--) {c[i] = 0;c[i] = a[i] - b[i] - borrow;if (c[i] >= 0) {borrow = 0;}else {c[i] = c[i] + K;borrow = 1;}}}void mul1(int *a, int b, int *c)
{long long tmp = 0;int carry = 0;for (int i=N-1; i>=0; i--) {tmp = (long long)a[i] * (long long)b + (long long)carry;c[i] = (int)(tmp % K);carry = (int)(tmp / K);}}void mul2(int *a, int *b, int *c)
{long long tmp = 0;int carry = 0;for (int i=N-1; i>=0; i--) {c[i] = 0;}for (int i=N-1; i>=0; i--) { // b[i]carry = 0;for (int j=N-1, idc=i; j>=0&&idc>=0; j--, idc--) { // a[j]tmp = (long long)a[j] * (long long)b[i] + (long long)carry + (long long)c[idc];c[idc] = (int)(tmp % K);carry = (int)(tmp / K);}}}int div(int *a, int b, int *c)
{long long tmp = 0;int remain = 0;for (int i=0; i<N; i++) {tmp = (long long)a[i] + (long long)remain * (long long)K;c[i] = (int)(tmp / b);remain = (int)(tmp % b);}return remain;}int calc(int n)
{// 请在这里补充代码,完成本关任务/********* Begin *********/int a[N] = {0};int c[N] = {0};a[N-1] = 1;for (int i=2; i<=n; i++) {mul1(a, i, c);for (int j=0; j<N; j++) {a[j] = c[j];c[j] = 0;}}int tot = 0;int tmp = 0;bool flag = true;for (int i=0; i<N; i++) {if (flag && a[i]==0) {continue;}if (flag) {tmp = a[i];flag = false;}else {tmp = a[i] + K;}while (tmp) {if (tmp % 10 == 0) {tot++;}tmp /= 10;}}return tot;/********* End *********/
}int main(int argc, const char * argv[]) {int n;scanf("%d", &n);int tot = calc(n);printf("%d\n", tot);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/58285.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

医学影像学基础:理解CT、MRI、X射线和超声等医学影像设备的基本工作原理和成像技术

目录 医学影像学基础 1. X射线成像 2. 计算机断层扫描&#xff08;CT&#xff09; 3. 磁共振成像&#xff08;MRI&#xff09; 4. 超声成像 综合对比 1、成像原理对比 2、安全性对比 3、应用领域对比 4、设备特点对比 总结 医学影像学基础 在医学影像学中&#xff0…

super和this

相同点&#xff1a; 1.都是Java中的关键字 2.都只可以在非静态方法中使用 3.在构造方法中使用必须是第一条语句并且二者不可以同时存在不同点&#xff1a; 1.this是当前对象的引用&#xff0c;super是子类对象从父类继承下来部分成员的引用 2.在非静态成员方法中&#xff0c;…

CSS、Less、Scss

CSS、Less和SCSS都是用于描述网页外观的样式表语言&#xff0c;但它们各自具有不同的特点和功能。以下是对这三者的详细阐述及区别对比&#xff1a; 详细阐述 CSS&#xff08;Cascading Style Sheets&#xff09; 定义&#xff1a;CSS是一种用来表现HTML或XML等文件样式的计算机…

etcd之etcd分布式锁及事务(四)

1、etcd分布式锁及事务 1.1 前言 分布式锁是控制分布式系统之间同步访问共享资源的一种方式。在分布式系统中&#xff0c;常常需要协调他们的动作。如 果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源&#xff0c;那么访问这些资源的时候&#xff0c;往往需要…

计算机网络-CSMA/CD协议笔记及“争用期”的理解

假设a和b是总线型网络上相距最远的两个节点。 从零这个时刻a节点会往信道上发送数据&#xff0c;那么a节点发送的第一个比特&#xff0c;需要经过τ这么长的时间&#xff0c;也就是经过一个单向的传播时延之后。它的这个信号才可以被最远的这个节点检测到。那如果b结点在τ这个…

六、深度剖析 Hadoop 分布式文件系统(HDFS)的数据存储机制与读写流程

深度剖析 Hadoop 分布式文件系统&#xff08;HDFS&#xff09;的数据存储机制与读写流程 在当今大数据领域当中&#xff0c;Hadoop 分布式文件系统&#xff08;HDFS&#xff09;作为极为关键的核心组件之一&#xff0c;为海量规模的数据的存储以及处理构筑起了坚实无比的根基。…

android aild 传递多个参数, in ,out,inout

在 HIDL 和 AIDL 中&#xff0c;方法参数的传递方式有所不同。HIDL 使用 generates 关键字来表示方法的返回值&#xff0c;而 AIDL 使用 in、out 和 inout 关键字来表示参数的传递方向。 HIDL 中的 generates 在 HIDL 中&#xff0c;generates 关键字用于指定方法的返回值。例…

https://huggingface.co/上的模型无法用linux服务器clone怎么办(只需要稍微改一下网址,就可以切换到镜像下载)

问题描述&#xff1a; 在ubuntu系统上&#xff0c;使用如下命令&#xff0c;克隆仓库&#xff0c;报无法访问错误&#xff1a; git clone https://huggingface.co/distilbert/distilroberta-base通用解决方案&#xff1a; 把下面部分更换&#xff1a; https://huggingface.…

内存泄漏的隐形陷阱:console.log

console.log 本身不会直接导致内存泄漏&#xff0c;但在特定的场景下&#xff0c;其使用方式可能间接引发内存泄漏问题&#xff0c;特别是在以下情况&#xff1a; 1. console.log 引用闭包或对象 console.log 输出的数据如果包含引用类型&#xff08;例如&#xff1a;对象、数…

Python 基础语法 - 逻辑运算符

逻辑运算符是用来做逻辑计算的&#xff0c;就像之前用到的比较运算符 &#xff0c;每一次比较其实就是一次条件判断&#xff0c;都会得到一个相应的True或者False的值&#xff0c;而逻辑运算符的操作数就是一个用来做条件判断的表达式或者变量 运算符说明and与or或not非 1. an…

【云原生】云原生与DevOps的结合:提升软件开发与交付的效率

目录 引言一、什么是云原生&#xff1f;1.1 云原生的核心原则1.2 云原生的技术栈1.3 云原生的优势 二、DevOps的概述2.1 DevOps的起源与发展2.2 DevOps文化的重要性2.3 DevOps工具链 三、云原生与DevOps的结合3.1 CI/CD的概念与重要性3.2 持续交付的实施策略3.3 整合CI/CD流程3…

数字IC后端实现Innovus |给各种IP子模块添加port buffer和antenna diode万能脚本

我们之前分享过在hierarchical flow后端实现中为了确保顶层flatten时timing signoff和physical signoff看到的情况和模块级看到的情况一致&#xff0c;我们会在模块io port添加io port buffer&#xff08;主要是timing&#xff0c;antenna一致性&#xff09;。实际上在芯片级我…

PSINS工具箱函数介绍——inserrplot

关于工具箱 i n s e r r p l o t inserrplot in

一个关于@JsonIgnore的isxxx()问题

一个关于JsonIgnore的问题 版本:2.13.5 <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><optional>true</optional></dependency>代码&#xff1a; Data public clas…

多源BFS问题(1)_01矩阵

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 多源BFS问题(1)_01矩阵 收录于专栏【经典算法练习】 本专栏旨在分享学习算法的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 1. 题…

el-select实现模糊搜索、远端搜索

el-select实现模糊搜索、远端搜索 实现代码&#xff1a; <template><div class"item-select-wrapper"><el-select v-model"value1" filterable"filterable" :disabled"disabled" remote"remote" clearable…

前端请求格式

1.multipart/form-data格式发送请求参数 什么时候用&#xff1a; 当后端API要求以表单的形式接收数据时&#xff0c;比如<input type"text" name"username">和<input type"password" name"password">&#xff0c;这些数据…

Java案例——屏蔽信息

首先这次的案例需要用到substring方法&#xff0c;先了解一下&#xff1a; 首先我们来加密一下电话号码&#xff1b; package String; public class Demo_06 {public static void main(String[] args) {// 定义一个电话号码字符串String phoneNumber"13111112598"…

精选:HR招聘管理工具Top5使用体验

作为企业招聘者&#xff0c;如何在选择中找到开启高效招聘之门的钥匙&#xff0c;成为了每一位企业招聘管理者必须面对的难题&#xff0c;在面对市场上琳琅满目的招聘工具&#xff0c;你是否也曾感到无头绪&#xff0c;不知所措&#xff1f;每个工具都声称自己拥有独特的优势和…

【MySQL】JDBC的连接

目录 一. 具体操作如下 1.注册驱动 二.实操 JDBC&#xff08;Java DataBase Connectivity&#xff09;java 数据库连接&#xff0c;是 JavaEE 平台下的技术规范&#xff0c;其定义了在 Java 语言中连接数据&#xff0c;执行 SQL 语句的标准&#xff0c;可以为多种关系数据库…