以下纯属是自己学习csp过程中的一些记录,方便自己后续复盘,随心写,不必当真。
题目791:高精度加法
算法思想:
什么是高精度? A.length<<10e6 ,a<<10e9
然后在这个情况下进行加减乘除如 A+B、A-B、A*b、A/b等的组合就是高精度运算。
我们普通的加法手算如下:
例如计算:567 + 28
先个位相加: 7 + 8 = 15,所以结果的个位是5,向十位进 1
再十位相加: 6 + 2 + 1(进位)= 9, 所以十位是 9,向百位进 0
再百位相加: 5 + 0 = 5, 所以结果的百位是 5
综上,计算结果为 595
算法计算思路:
计算 567 + 28
用 a, b 两个字符串存储输入。a = 567, b = 28
为了方便计算,(因为加法要从各位开始,倒序存放符合计算规律)将两个数分别 倒序 存放在 A, B 两个整数数组中。 A = [7, 6, 5], B = [8, 2]
新建整数数组 res保存结果,整型变量 c保存进位,初始 c= 0.
将各个位上的数字相加,求出结果对应位上的数字和进位。
例如对个位计算: A[0] + B[0] = 7 + 8 = 15, 结果个位上是 5,进位是 1. 所以 res[0] = 5, 进位 c = 1
最后把结果数组 res 中就保存了计算倒序结果,倒序输出就是答案。
代码实现:O(n+m)
// 高精度加法
#include
#include
using namespace std;
vector add(vector &a, vector &b)
{// c为进位int c = 0;vector res;// 如果数组a和b有没遍历完的,进行循环for (int i = 0; i < a.size() || i < b.size(); i++){// 没遍历完的,加到进位中 此时c=a[i]+b[i]+cif (i < a.size())c += a[i];if (i < b.size())c += b[i];// 结果只需要保存c对10的模res.push_back(c % 10);// c变为c/10 进位为1下次循环加c /= 10;}// 如果数组全部遍历完,还需要考虑最高位是否有进位,若有则最高位+1if (c)res.push_back(1);return res;
}
int main()
{string n, m;cin >> n >> m;vector a, b;// a,b都为字符串,可以遍历,将每个字符转为int 存入数组 为后续加法做准备for (int i = n.size() - 1; i >= 0; i--)a.push_back(n[i] - '0');for (int i = m.size() - 1; i >= 0; i--)b.push_back(m[i] - '0');auto c = add(a, b);// 输出结果for (int i = c.size() - 1; i >= 0; i--)cout << c[i];return 0;
}
题目792:高精度减法

算法思想:
和高精度+法差不多,值得注意的是:
1、减法的借位处理,不管借不借位,都可以把(t+10)%10加进数组!
2、相减为负数的处理:先进行判断大小,保证减法都是大减小,最后考虑符号问题。
3、前导0的处理
代码实现:O(n)
#include
#include
#include
using namespace std;
// 判断a>=b
bool cmp(vector &a, vector &b)
{// a,b长度不一,长的大if (a.size() != b.size())return a.size() > b.size();// 长度相等 逐位比较 最高位在最后面所以反着比for (int i = a.size() - 1; i >= 0; i--)if (a[i] != b[i]) return a[i] > b[i];// 相等返回truereturn true;
}
vector sub(vector &a, vector &b)
{vector res;int t = 0;// 减法从个位开始for (int i = 0; i < a.size(); i++){// t=0则 t=a[i] t=1则t=a[i]-1t = a[i] - t;// 如果被减数还有位数if (i < b.size())// t减去被减数t -= b[i];// t<0则t=10+t 借位 t>=0则t=t 不借位res.push_back((t + 10) % 10);// 借位则t=1 否则t=0if (t < 0) t = 1;else t = 0;}// 去除多余的0 003=3while (res.size() > 1 && res.back() == 0) res.pop_back();return res;
}int main(){string n, m;cin >> n >> m;vector a, b;//反向读取字符串for (int i = n.size() - 1; i >= 0; i--)a.push_back(n[i] - '0');for (int i = m.size() - 1; i >= 0; i--)b.push_back(m[i] - '0');// 调用函数比大小if (cmp(a, b)){auto c = sub(a, b);for (int i = c.size() - 1; i >= 0; i--)cout << c[i];}else{auto c = sub(b, a);//带上-号cout<<"-";for (int i = c.size() - 1; i >= 0; i--)cout << c[i];}return 0;}
题目793:高精度乘法

算法思想:
和高精度+-法差不多,值得注意的是:
1、乘法的进位处理
2、特殊判断,如果×0的话,直接输出结果
3、注意最高位,最后一次乘完要判断t的大小,为1说明最高位有进位,手动添加进数组即可。
代码实现:O(n)
#include
#include
#include
using namespace std;
//高精度乘法
vector mul(vector& a,int b){vector res;//进位int t=0;//如果b为0,则结果为0 不必进行乘法运算if(b==0) {res.push_back(0);return res;}//每一位都与b相乘for(int i=0;i>a>>b;vector A;//逆序存入数组for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0');auto c=mul(A,b);for(int i=c.size()-1;i>=0;i--) cout<
题目794:高精度除法

算法思想:
和高精度+-×法差不多,值得注意的是:
1、除法比较特殊,需要从最高位开始除数,所以for循环倒序,因为最后一位存的是最高位。
2、因为除法存在第一位是0的情况,所以要去除前导0。
3、不懂得友友可以自己手算模拟一下!很清晰!

代码实现:O(n)
#include
#include
#include
#include
using namespace std;
vector div(vector &a, int b, int &r)
{vector res;// 除法需要从最高位开始算for (int i = a.size() - 1; i >= 0; i--){// 余数操作r = r * 10 + a[i];// 存入商res.push_back(r / b);// 更新余数r = r % b;}// 反转数组 去除多余的前导0 因为除法第一个数一定是0reverse(res.begin(), res.end());while (res.size() > 1 && res.back() == 0)res.pop_back();return res;
}
int main()
{string a;int b;cin >> a >> b;vector A;// 反转存入数组for (int i = a.size() - 1; i >= 0; i--)A.push_back(a[i] - '0');// 余数int r = 0;auto c = div(A, b, r);for (int i = c.size() - 1; i >= 0; i--)cout << c[i];cout << endl<< r << endl;return 0;
}
欢迎友友评论区讨论,有不足请指出,大家一起交流进步!