高精度加法讲解-And-2021年ACM竞赛班训练2021.5.13-问题 E: Python大法好-题解

Posted Tisfy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高精度加法讲解-And-2021年ACM竞赛班训练2021.5.13-问题 E: Python大法好-题解相关的知识,希望对你有一定的参考价值。

C++高精度加法

这里介绍一种通过运算符重载实现高精度加法的方法。

实现高精度加法,会议一下小学老师是怎么教的就可以了。
这只是用计算机模拟实现,该进位就进位,细心就好。

可以定义一个结构体(类也行),叫MyNum。

struct myNum{
    string num;  // 里面的数是倒着的
};

为什么不直接string s呢,因为string已经对输入输出等重载过了。
为了后续方便,此处采用倒着存储的方法,即:如果一个数是123,那么可以:

myNum a;
a.num = "321";  // 倒着存储

之后先重载输入输出吧,这个简单一些。
输入:

istream& operator >> (istream &in, myNum& a)  // 重载运算符“ >> ”, 记得a前面加上引用。
{
    in>>a.num;  // 如果要用cin,那么这就相当于cin>>a.num
    reverse(a.num.begin(),a.num.end());  // 把a.num倒置
    return in;
}

同理输出:

ostream& operator << (ostream &out, myNum a)
{
    reverse(a.num.begin(),a.num.end());
    out<<a.num;
    return out;
}

emmm,实在不行就记住吧,或者说先理解一下后面的加减法的重载,也许再理解这个会简单一些。

下面来介绍如何重载加法:
假如加法是实现两个myNum的字符串的拼接,那么可以写为:

myNum operator + (myNum &a, myNum &b)  // 重载运算符“ + ”,返回类型是myNum,参数类型是myNum和myNum,即要实现myNum类型的两个结构体a和b的“相加”(这里是字符串拼接)
{
	myNum c;  // 定义一个myNum类型的c
	c.num=a.num+b.num;  // c.num是a和b的num字符串的拼接
	return c;  // 返回“相加结果”c
}

为什么要重载呢?
你想啊,自定义的高精度类型myNum不是C++自带的类型,那么你的编译器怎么会知道myNum如何相加减呢?因此就需要你来手动定义。
为了使myNum使用起来就像int一样,我们重载+、>>等运算符,编译器就知道两个myNum的相加规则了。

回忆一下小学时学的加法运算法则:
两个数相加,先把长的数放在上面,把短的数放在下面:
小学加法
然后,对短的数的每一位,加上长的数的相对应的那一位再加上前面的进位,除以10取余,余数是这一位的答案,商是新的进位。
长的数的超出短的数的部分就只需要考虑进位了。

代码如下:

myNum operator + (const myNum&a, const myNum&b)  // 重载运算符+,返回类型是myNum,+号两边类型都是myNum
{
    myNum ans;  // a+b的结果
    int la=a.num.size(),lb=b.num.size();  // a的长度、b的长度
    string first,second;  // 第一个数(长的数)和第二个数(短的数)
    if(la<lb)first=b.num,second=a.num,swap(la,lb);//第一个长于第二个
    else first=a.num,second=b.num;
    int JinWei=0;  // 进位
    for(int i=0;i<lb;i++)  // 短的数的每一位
    {
        int thisNum=first[i]-'0'+second[i]-'0'+JinWei;  // 这个数 = 短的数的这一位 + 长的数的对应的这一位 + 上一位的进位
        ans.num+=thisNum%10+'0';  // 答案的这个数就是这个数模10
        JinWei=thisNum/10;  // 进位变成这个数/10
    }
    for(int i=lb;i<la;i++)  // 遍历长的数的超出短的数的部分
    {
        int thisNum=first[i]-'0'+JinWei;  // 这个数 = 长的数的对应的这一位 + 上一位的进位 (没有短的数了)
        ans.num+=thisNum%10+'0';  // 同上一个循环
        JinWei=thisNum/10;
    }
    if(JinWei)  // 如果计算完毕还有进位
    {
        ans.num+=JinWei+'0';  // 答案就再增加一位
    }
    return ans;  // 返回答案
}

既然已经实现了上述的重载,那么使用起来就跟正常的int类型差不多了。
定义:

int int_a;
myNum myNum_a;

输入:

cin>>int_a;
cin>>myNum_a;

输出:

cout<<int_a;
cout<<myNum_a;

相加:

int int_c=int_a+int_b;
myNum myNum_c=myNum_a+myNum_b;

如果要实现两个高精度的数相加,代码就如下:

#include <bits/stdc++.h>
using namespace std;
#define mem(a) memset(a, 0, sizeof(a))
#define dbg(x) cout << #x << " = " << x << endl
#define fi(i, l, r) for (int i = l; i < r; i++)
#define cd(a) scanf("%d", &a)
typedef long long ll;
struct myNum{
    string num;//里面的数是倒着的
};
myNum operator + (const myNum&a, const myNum&b)
{
    myNum ans;
    int la=a.num.size(),lb=b.num.size();
    string first,second;
    if(la<lb)first=b.num,second=a.num,swap(la,lb);
    else first=a.num,second=b.num;
    int JinWei=0;
    for(int i=0;i<lb;i++)
    {
        int thisNum=first[i]-'0'+second[i]-'0'+JinWei;
        ans.num+=thisNum%10+'0';
        JinWei=thisNum/10;
    }
    for(int i=lb;i<la;i++)
    {
        int thisNum=first[i]-'0'+JinWei;
        ans.num+=thisNum%10+'0';
        JinWei=thisNum/10;
    }
    if(JinWei)
    {
        ans.num+=JinWei+'0';
    }
    return ans;
}

istream& operator >> (istream &in, myNum& a)
{
    in>>a.num;
    reverse(a.num.begin(),a.num.end());
    return in;
}

ostream& operator << (ostream &out, myNum a)
{
    reverse(a.num.begin(),a.num.end());
    out<<a.num;
    return out;
}

int main()
{
	myNum a, b;
	cin>>a>>b;
	cout<<a+b<<endl;
	return 0;
}

那么对于我校OJ的这道题:


Python大法好

传送门

时间限制:1秒
空间限制:128M


题目描述

自从20世纪90年代初Python语言诞生至今,它已被逐渐广泛应用于系统管理任务的处理和Web编程。

Python的创始人为荷兰人吉多·范罗苏姆 (Guido van Rossum)。1989年圣诞节期间,在阿姆斯特丹,Guido为了打发圣诞节的无趣,决心开发一个新的脚本解释程序,作为ABC语言的一种继承。之所以选中Python(大蟒蛇的意思)作为该编程语言的名字,是取自英国20世纪70年代首播的电视喜剧《蒙提·派森的飞行马戏团》(Monty Python’s Flying Circus)。

Python是完全面向对象的语言。函数、模块、数字、字符串都是对象。并且完全支持继承、重载、派生、多继承,有益于增强源代码的复用性。Python支持重载运算符和动态类型。相对于Lisp这种传统的函数式编程语言,Python对函数式设计只提供了有限的支持。有两个标准库(functools, itertools)提供了Haskell和Standard ML中久经考验的函数式程序设计工具。

有些比赛,不限制语言种类,遇到一些对时间要求不高的,用C缺较复杂的题目,不妨试试用python来做。

比如要计算大整数加法,用Python就很容易(此处没有语言偏见)。

Python 已经成为最受欢迎的程序设计语言之一。自从2004年以后,python的使用率呈线性增长。Python 2于2000年10月16日发布,稳定版本是Python 2.7。Python 3于2008年12月3日发布,不完全兼容Python 2。 2011年1月,它被TIOBE编程语言排行榜评为2010年度语言。

现在给你两个换行相隔的正整数,范围是1~10的100000次方,保证没有前导零,请你计算这两个数的和,同时也请不要输出前导0。

Python本身被设计为可扩充的。并非所有的特性和功能都集成到语言核心。Python提供了丰富的API和工具,以便程序员能够轻松地使用C语言、C++、Cython来编写扩充模块。

由于Python语言的简洁性、易读性以及可扩展性,在国外用Python做科学计算的研究机构日益增多,一些知名大学已经采用Python来教授程序设计课程。

非输入输出相关部分来自百度百科


输入描述

这是一道阅读理解题,输入描述就在题目中。


输出描述

当然也在题目中。
哦,对了,不在题目描述中的只有一点:这次比赛不能用Python


样例一

输入

2
2

输出

4

题目分析

  • 迅速从题目中分析获得题意的能力还是很重要的。如果这是一道签到题,能很快读懂题的话排名将会是多么的酷!
  • 可以掌握一下C++里的一些与重载相关的知识,计科人,现在会了大二就轻松了。

注意事项

本次为了减低一点难度系数,输入只有正整数。因此只需要高精度加法即可。


AC代码

#include <bits/stdc++.h>
using namespace std;
#define mem(a) memset(a, 0, sizeof(a))
#define dbg(x) cout << #x << " = " << x << endl
#define fi(i, l, r) for (int i = l; i < r; i++)
#define cd(a) scanf("%d", &a)
typedef long long ll;
struct myNum{
    string num;//里面的数是倒着的
};
myNum operator + (const myNum&a, const myNum&b)
{
    myNum ans;
    int la=a.num.size(),lb=b.num.size();
    string first,second;
    if(la<lb)first=b.num,second=a.num,swap(la,lb);//第一个长于第二个
    else first=a.num,second=b.num;
    int JinWei=0;
    for(int i=0;i<lb;i++)
    {
        int thisNum=first[i]-'0'+second[i]-'0'+JinWei;
        ans.num+=thisNum%10+'0';
        JinWei=thisNum/10;
    }
    for(int i=lb;i<la;i++)
    {
        int thisNum=first[i]-'0'+JinWei;
        ans.num+=thisNum%10+'0';
        JinWei=thisNum/10;
    }
    if(JinWei)
    {
        ans.num+=JinWei+'0';
    }
    return ans;
}

istream& operator >> (istream &in, myNum& a)
{
    in>>a.num;
    reverse(a.num.begin(),a.num.end());
    return in;
}

ostream& operator << (ostream &out, myNum a)
{
    reverse(a.num.begin(),a.num.end());
    out<<a.num;
    return out;
}

int main()
{
	myNum a, b;
	cin>>a>>b;
	cout<<a+b<<endl;
	return 0;
}

勇士,想要练练高精度减法吗?

原创不易,转载请附上原文链接哦~
Tisfy:https://letmefly.blog.csdn.net/article/details/116712749

以上是关于高精度加法讲解-And-2021年ACM竞赛班训练2021.5.13-问题 E: Python大法好-题解的主要内容,如果未能解决你的问题,请参考以下文章

集合划分讲解-And-2021年ACM竞赛班训练2021.5.20-问题 E: 登上火星-题解

2021年ACM竞赛班训练(十一)

2021年ACM竞赛班训练 E题 调皮的摩尔

buctoj2021年ACM竞赛班训练题解

2021年ACM竞赛班训练2021.5.20-问题 E: 调皮的摩尔-题解

2021年ACM竞赛班训练2021.5.21-问题 A: 尝试看到这道题吧-题解