P1303 A*B Problem

P1303 A*B Problem

题目

给出两个非负整数,求它们的乘积。

输入

输入共两行,每行一个非负整数。

输出

输出一个非负整数表示乘积。

样例

输入

1 
2

输出

2

提示

每个非负整数不超过 102000


思路

根据题意,乘数的数据最大范围是 102000,需要使用高精度乘高精度的算法。将每个乘数以字符串读取并倒序存储在整型数组中,参考竖式乘法运算的过程进行计算。

设两个乘数分别为 a3a2a1b2b1,可以得到以下竖式

其中:

c11=b1×a1,c12=b1×a2,c13=b1×a3

c21=b2×a1,c22=b2×a2,c23=b2×a3

c1=c11,c2=c12+c21,c3=c13+c22,c4=c23

做完乘法后可以总结出规律:乘积第 (i+j1) 位的值为 ci+j1=((ai×bj))/10+进位”,其中 1ilena,1jlenb;乘积位 ci+j1 计算后大于等于 10,则向 ci+j 进位,ci+j1 位留下除以 10 的余数;乘积的长度最大值为 lenalenb 的和,另外在乘积输出前需要将前导零去掉。

for (int i = 1; i <= lena; i ++ )
{
    x = 0;
    for (int j = 1; j <= lenb; j ++ )
    {
        x = a[i] * b[j] + x / 10 + c[i + j - 1];
        c[i + j - 1] = x % 10;
    }
    c[i + lenb] = x / 10;
}
lenc = lena + lenb;
while (c[lenc] == 0 && lenc > 1) // 去掉多余的前导 0
    lenc --;

代码一

#include <bits/stdc++.h>

using namespace std;

char a1[2010], b1[2010];
int a[2010], b[2010], c[4000010], lena, lenb, lenc, x;

void read()
{
	scanf("%s %s", a1, b1);
	lena = strlen(a1);
	lenb = strlen(b1);
	for (int i = 0; i <= lena - 1; i ++ )
		a[lena - i] = a1[i] - 48;
	for (int i = 0; i <= lenb - 1; i ++ )
		b[lenb - i] = b1[i] - 48;
}

void mul()
{
	for (int i = 1; i <= lena; i ++ )
	{
		x = 0;
		for (int j = 1; j <= lenb; j ++ )
		{
			x = a[i] * b[j] + x / 10 + c[i + j - 1];
			c[i + j - 1] = x % 10;
		}
		c[i + lenb] = x / 10;
	}
	lenc = lena + lenb;
	while (c[lenc] == 0 && lenc > 1) // 去掉前导 0
		lenc --;
}

void print()
{
	for (int i = lenc; i >= 1; i -- )
		cout << c[i];
}

int main()
{
	read();
	mul();
	print();
	return 0;
}

代码二:重载运算符

#include <bits/stdc++.h>

using namespace std;

char str[2010];

struct node
{
	int len, s[4010];
	node()
	{
		len = 0;
		memset(s, 0, sizeof(s));
	}
};

node operator * (const node &a, const node &b)
{
	node c;
	c.len = a.len + b.len - 1;
	if ((a.len == 1 && a.s[1] == 0) || (b.len == 1 && b.s[1] == 0))
	{
		c.len = 1;
		c.s[1] = 0;
		return c;
	}
	for (int i = 1; i <= a.len; i ++ )
	{
		for (int j = 1; j <= b.len; j ++ )
		{
			c.s[i + j - 1] += a.s[i] * b.s[j];
			c.s[i + j] += c.s[i + j - 1] / 10;
			c.s[i + j - 1] %= 10;
		}
	}
	if (c.s[c.len + 1])
	{
		int x = c.s[c.len + 1], len = c.len;
		while (x)
		{
			c.s[++ len] = x % 10;
			x /= 10;
		}
		c.len = len;
	}
	return c;
}

node read()
{
	scanf("%s", str);
	int len = strlen(str);
	node a;
	a.len = len;
	for (int i = 0; i < len; i ++ )
		a.s[len - i] = str[i] - '0';
	return a;
}

void print(node a)
{
	for (int i = a.len; i >= 1; i -- )
		printf("%d", a.s[i]);
}

int main()
{
	node a, b, c;
	a = read();
	b = read();
	c = a * b;
	print(c);
	return 0;
}
posted @   IronMan_PZX  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
Title
点击右上角即可分享
微信分享提示