1 条题解
-
0
一个好的学生,要学会预判老师今天想讲什么并且提前交上去题解免责声明
代老师认为该代码使用的方法晦涩难懂(就是个fw!),不建议学习使用。标准答案参考代老师提交的AC代码。本文仅代表个人观点,如有不理解的地方请询问代老师并且对照标答进行修改学习
高精度算法-2
__int128也最多只提供到±2^127-1,如果需要更大数字的计算,如题目中所说的200位(比如1*10^114),则需要另一种定义方法来进行计算。遗憾的是,标准的C++函数并没有提供更大的整形范围了。但是!字符串的长度是可以随意定义的,那么高精度算法就产生了——把数字存在字符串的每一位中。
那么问题来了,字符串并不能随意的加减乘除,所以需要一种算法来对这一串数字进行操作。显而易见的,可以直接进行加减乘除运算的还得是int型,因此我们可以将字符串中的数字转换至一个数组的每一位种,再按照小学的列竖式方法进行运算。(为什么要用字符串输入而不是直接输入数组?那输入就得是这样了:1 1 4 5 1 4,显然,我们并不想每一位都敲一个空格)
高精度减法
基础原理:列竖式。对数组的每一位进行减法运算,如果相减数字小于十则+10,并且前一位的数字大小-1(即小学概念中的借位)。 其余在代码中展示。
#include<bits/stdc++.h> using namespace std; string jianfa(string a1, string b1) //定义减法函数 //方便进行修改然后去水高精度加法(划掉) { int a[200]={},b[200]={0},ans[200]={0}; //a,b数组的每一位分别对应字符串中的每一位 string fanhui=""; //返回的结果 if((a1<b1&&a1.size()<= b1.size())||(b1.size()>a1.size())) return "-"+jianfa(b1,a1); //如果两数长度不一致,则再次调用 //遵循 大减小 原则 for(int i=a1.size();i>0;i--) a[i]=a1[a1.size()-i]-'0'; for(int i=b1.size();i>0;i--) b[i]=b1[b1.size()-i]-'0'; //转换每一位数字 //此处为翻转转换,即比如123,此时a[]为321,方便后续运算 int maxx=max(a1.size(),b1.size()); //定义maxx为两个数字中长度最长的一个数字 的长度 for(int i=1;i<=maxx;i++) { if(a[i]<b[i]) //如果当前位的 a<b 则借位,再相减,并且上一位减一 { a[i+1]--; a[i]+=10; } ans[i]=a[i]-b[i]; //ans为存储答案数字的数组 }//减法运算主体 while(ans[maxx]==0) //题目规定不得输出多余的0,如0001,则需要将前三个‘0’去掉 maxx--; //如果这一位等于0就让最终答案的长度减一 再次循环 //详细解释:假设答案为0001 此时maxx为4,循环第一次后maxx-1,maxx=3 //仍为0,则继续-1,循环往复 if(maxx<1) //如果答案的位数<1,即全部为0的情况,直接返回0 return "0"; for(int i=maxx;i>0;i--) fanhui+=ans[i]+'0'; //答案数组转换为字符串,当然也可以循环输出数组 return fanhui; //返回答案字符串 } int main() { string in1,in2; //定义两个字符串 cin>>in1>>in2; //输入 cout<<jianfa(in1,in2); //直接输出函数返回值 return 0; }
- 1
信息
- ID
- 389
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 6
- 标签
- (无)
- 递交数
- 64
- 已通过
- 22
- 上传者