题解:P1303 A*B Problem
songliunuo
·
·
题解
水体讲解, 简单高精度。
前言
感谢 [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) 。