专栏文章

题解:P1303 A*B Problem

P1303题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miouci3i
此快照首次捕获于
2025/12/03 01:17
3 个月前
此快照最后确认于
2025/12/03 01:17
3 个月前
查看原文
水体讲解, 简单高精度。

前言

10200010^{2000} 没有任何变量能一次性存下,long long 也只有 101810^{18}
感谢 liangyunzhi2012 的帮助、支持与指导。

思路

类似于小学数学中的竖式乘法。

过程解释

CPP
  123
 x123
-------
  369
 246
123
-------
15129
过程为:
  1. 把第二行的 123 的最后一位 3 乘第一行的 123 , 等于 369
  2. 把第二行的 123 的倒数第二位 2 乘第一行的 123 , 等于 246
  3. 把第二行的 123 的第一位 1 乘第一行的123, 等于 123
  4. 369×1=369369 \times 1 = 369( 第几位 ) ; 246×10=2460246 \times 10 = 2460139×100=13900139 \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{作弊者}} 。 具体细则请查 看洛谷社区规则
提交题解前请务必阅读 《洛谷主题库题解规范》

评论

0 条评论,欢迎与作者交流。

正在加载评论...