题解:P1303 A*B Problem

· · 题解

水体讲解, 简单高精度。

前言

感谢 [liangyunzhi2012](https://www.luogu.com.cn/user/1648896) 的帮助、支持与指导。 ## 思路 类似于小学数学中的竖式乘法。 ### 过程解释 ``` 123 x123 ------- 369 246 123 ------- 15129 ``` 过程为: 1. 把第二行的 123 的最后一位 3 乘第一行的 123 , 等于 **369** ; 2. 把第二行的 123 的倒数第二位 2 乘第一行的 123 , 等于 **246** ; 3. 把第二行的 123 的第一位 1 乘第一行的123, 等于 **123** ; 4. $ 369 \times 1 = 369 $( 第几位 ) ; $ 246 \times 10 = 2460 $ ;$ 139 \times 100 = 13900 $; 5. 369 + 2460 + 13900 = 15129。 ### 带你写题 头文件及基础定义。 ```cpp #include<bits/stdc++.h> using namespace std; string a1,b1; int a[2005],b[2005],c[4005]; //没什么好讲的吧 int main(){//主函数 ``` 输入, 然后倒序放入数组。 ```cpp cin>>a1; reverse(a1.begin(),a1.end()); for(int i=0;i<a1.size();i++){ a[i]=a1[i]-48; } cin>>b1; reverse(b1.begin(),b1.end()); for(int i=0;i<b1.size();i++){ b[i]=b1[i]-48; } ``` 特判, 防止第一个数或第二个数为 **0** 。 ```cpp if(a1=="0"||b1=="0"){ cout<<0;//直接输出 return 0;//结束 } ``` 乘法计算枚举模拟过程, 不考虑进位。 ```cpp for(int i=0;i<a1.size();i++){ for(int j=0;j<b1.size();j++){ c[i+j]+=a[i]*b[j]; } } ``` 进位判断。 ```cpp int len=a1.size()+b1.size()-1;//两个数的长度之和,简单来说就是得数的长度,注意需要减1。 for(int i=0;i<len;i++){ c[i+1]+=c[i]/10; c[i]%=10; } ``` 特判及输出,特判是为了防止少输出一位。 第一种写法 ```cpp if(c[len]){ len++; } for(int i=len-1;i>=0;i--){ cout<<c[i]; } ``` 第二种写法 ```cpp if(c[len]){ cout<<c[len]; } for(int i=len;i>=0;i--){ cout<<c[i]; } ``` 注意要反向输出。 ### 总体答案(精讲) ```cpp #include<bits/stdc++.h> using namespace std; string a1,b1;//定义基础数,太大所以需要string int a[2005],b[2005],c[4005];//a=a1,a1的哪一位等于数组的哪一位,b=b1,b1的哪一位等于数组的哪一位,c得数 int main(){//主函数 cin>>a1;//输入a1 reverse(a1.begin(),a1.end());//把a1变成倒序 for(int i=0;i<a1.size();i++){//循环导入 a[i]=a1[i]-48;//把a1转到a } cin>>b1;//输入b1 reverse(b1.begin(),b1.end());//把b1变成倒序 for(int i=0;i<b1.size();i++){//循环导入 b[i]=b1[i]-48;//把b1转到b } if(a1=="0"||b1=="0"){//特判是否为0 cout<<0;//直接输出 return 0;//结束程序 } for(int i=0;i<a1.size();i++){//第一层循环 for(int j=0;j<b1.size();j++){//第二层循环 c[i+j]+=a[i]*b[j];//进行模拟乘法,注意因为有可能里面有数所以要+= } } int len=a1.size()+b1.size()-1;//定义后面用到的成长度计数,注意要减1 for(int i=0;i<len;i++){//循环进位 c[i+1]+=c[i]/10;//进位 c[i]%=10;//自减,保留个位 } if(c[len]){//特判 len++;//加一,防止前面有数 } for(int i=len-1;i>=0;i--){//倒序循环 cout<<c[i];//输出 } return 0; //完结撒花 } ``` ## 注意 ### **$\color{red}{\text{题解仅供学习参考使用}}$** 抄袭、 复制题解, 以达到刷 AC 率 / AC 数量或其他目的的行为, 在洛谷是严格禁止的。 洛谷非常重视 **学术诚信** 。 此类行为将会导致您成为 $\color{brown}{\text{作弊者}}$ 。 具体细则请查 [看洛谷社区规则](https://help.luogu.com.cn/rules/community) 。 提交题解前请务必阅读 [《洛谷主题库题解规范》](https://help.luogu.com.cn/rules/academic/solution-standard) 。