【Sowu_0077】高精度加、减、乘模板题作业

1、高精度加法

模板:洛谷 P1601 A+B Problem(高精)

需注意的地方

1、高精度加法进位的应用
2、最后一位进位的情况

AC代码

#include
#include
#include
using namespace std;
#define N 507
char a[N], b[N];
int num1[N], num2[N];
int num[N];
int main() {
	cin >> a >> b;
	memset(num, 0, sizeof(num));
	int len1 = strlen(a);
	int len2 = strlen(b);
	int numlen = 0, i;
	for (i = 0; i < len1; i++)
		num1[i] = a[i] - '0';
	for (i = 0; i < len2; i++)
		num2[i] = b[i] - '0';

	for (i = 0; len1 > 0 || len2 > 0; i++) {
		if (len1 > 0 && len2 > 0)
		{
			num[i] += num1[len1 - 1] + num2[len2 - 1];
			len1--, len2--;
		}
		else if (len1 == 0)
		{
			num[i] += num2[len2 - 1];
			len2--;
		}
		else if (len2 == 0)
		{
			num[i] += num1[len1 - 1];
			len1--;
		}
		if (num[i] >= 10)//加法进位
		{
			num[i + 1]++;
			num[i] %= 10;
		}
	}
	if (num[i] > 0)//注意若最后一位有进位,最后数组总长度要加1
		i++;
	numlen = i;
	for (i = numlen - 1; i >= 0; i--)
		cout << num[i];
	return 0;
}

2、高精度减法

模板:洛谷 P2142 高精度减法

需注意的地方

1、高精度减法借位运用
2、先判断答案是否为负数,若是负数,倒过来减最后再加个负号就行了。
3、特判答案为0的情况

AC代码

#include
#include
#include
using namespace std;
#define N 10087
char a[N], b[N];
int num1[N], num2[N];
int num[N];
int len1, len2;
int F() {
	if (len1 > len2)
		return true;
	else if (len1 == len2)
	{
		int i=0, j =0;
		while (num1[i] == num2[j])
		{
			i++, j++;	
			if (i == len1)//注意不要忘记两数相等的情况
				return 2;
		}
		if (num1[i] > num2[j])
			return true;
		else
			return false;
	}
	else
		return false;
}
int main() {
	cin >> a >> b;
	memset(num, 0, sizeof(num));
	len1 = strlen(a);
	len2 = strlen(b);

	int numlen = 0, i;
	for (i = 0; i < len1; i++)
		num1[i] = a[i] - '0';
	for (i = 0; i < len2; i++)
		num2[i] = b[i] - '0';

	int flag = F();
	if (!flag) {
		for (i = 0; i < len1; i++) {
			int x = num1[i];
			num1[i] = num2[i];
			num2[i] = x;
		}
		while (i < len2)
		{
			num1[i] = num2[i];
			i++;
		}
		int y = len1;
		len1 = len2, len2 = y;
	
	}
	
	for (i = 0;len2 > 0||len1>0; i++) {
		if(len2>0)
		{
			num[i] += num1[len1 - 1] - num2[len2 - 1];
			len1--, len2--;
		}
		else if (len2 <= 0)
		{
			num[i] += num1[len1 - 1];
			len1--;
		}
		if (num[i] < 0)//减法借位
		{
			num[i + 1]--;
			num[i] += 10;
		}
	}
	numlen = i;
	if(flag==2)
		cout << 0;
	else
	{
		if (!flag)
			cout << "-";
			while (num[numlen - 1] == 0)
				numlen--;
			for (i = numlen - 1; i >= 0; i--)
				cout << num[i];
	}
	return 0;
}

3、高精度乘法

模板题:洛谷 P1303 A*B Problem

高精度乘法分析

参考博客:点我

【核心代码】
for (i = 1; i <= len1; i++)
	{
		for (j = 1; j <= len2; j++)
		{
			num[i + j - 1] += num1[i] * num2[j];
			num[i + j] += num[i + j - 1] / 10;
			num[i + j - 1] %= 10;
		}
	}
【分析】

在这里插入图片描述

核心代码(乘法运算部分)是由模拟乘法竖式算出来的:
(1) 数1的倒数第i位与数2的倒数第j位相乘所得到的值应存在结果的倒数第i+j-1位上。
(2) 如果结果的i+j-1位大于9,则进位到i+j位。
【举例】 :比如说当i=j=1、即num1[i]=3,num2[j]=5时,
num[i+j-1]=num1[1]*num2[1]%10=5;
num[i+j] + =num1[1]*num2[1]/10=0+1=1;
即当前:num[1]=5,num[2]=1(后续这个num[2]还会继续累加,对应举例中标黄部位);

需注意的地方:

1、高精度乘法进位的掌握~~
2、i位数 与 j位数 相乘,其结果最多为 i+j 位。
3、注意答案为0的情况和前缀有0的情况。

AC代码

#include
#include
#include
using namespace std;
#define N 2007
char a[N], b[N];
int num1[N], num2[N];
int num[N];
int main() {
	cin >> a >> b;
	memset(num, 0, sizeof(num));
	int len1 = strlen(a);
	int len2 = strlen(b);
	int numlen = 0, i,j;
	
	for (i = 1; i <= len1; i++)
		num1[i] = a[len1-i] - '0';
	for (i = 1; i <= len2; i++)
		num2[i] = b[len2-i] - '0';
	
	for (i = 1; i <= len1; i++)
	{
		for (j = 1; j <= len2; j++)
		{
			num[i + j - 1] += num1[i] * num2[j];
			
			num[i + j] += num[i + j - 1] / 10;
			num[i + j - 1] %= 10;
		}
	}

	numlen = i+j;
	if (num[numlen+ 1] > 0)//注意若最后一位有进位,最后数组总长度要加1
		numlen++;
	while (num[numlen] == 0&&numlen>1)//消掉前缀多余的0,若numlen==1且num[numlen] == 0,则答案为0
		numlen--;
	for (i = numlen ; i >0; i--)
		cout << num[i];
	return 0;
}

你可能感兴趣的:(ACM作业,算法竞赛)