Bootstrap

蓝桥备赛(22)算法篇【高精度】

一、高精度

当数据的值特别大 , 各种类型都存不下的时候 , 此时就需要用高精度算法来计算加减乘除:

1) 先用字符串读入这个数 , 然后用数组逆序存储该数的每一位

2)利用数组 , 模拟加减乘除运算的过程

高精度算法本质上还是模拟算法 , 用代码模拟小学 列竖式计算加减乘除的过程 。

二、高精度加法

P1601 A+B Problem(高精) - 洛谷

#include <iostream>
using namespace std;

const int N = 1e6 +10;
int a[N],b[N],c[N];
int la,lb,lc;

//高精度加法模板  --- c = a+b
void add(int c[],int a[],int b[])
{
	for(int i = 0;i<lc;i++)
	{
		c[i] += a[i] + b[i];//对应位相加,在加上进位
		c[i + 1] += c[i]/10;//处理进位
		c[i]%=10; //处理余数 
	}
	if(c[lc])lc++;
}
 
int main()
{
	string x,y;
	cin >> x >> y;
	//1.拆分每一位,逆序放进数组中
	la = x.size() ;lb = y.size() ;lc = max(la,lb);
	for(int i = 0;i<la;i++)a[la-1-i] = x[i] - '0';
	for(int i = 0;i<lb;i++)b[lb-1-i] = y[i] - '0';
	
	//2.模拟加法的过程
	add(c,a,b); //c = a+b
	
	//3.输出结果
	for(int i = lc-1;i>=0;i--)cout << c[i]; 
	return 0;
}

三、高精度减法

P2142 高精度减法 - 洛谷

#include <iostream>
using namespace std;

const int N = 1e6 + 10;
int a[N],b[N],c[N];
int la,lb,lc;

//比大小 
bool cmp(string & x,string & y)
{
	//先比较长度
	if(x.size() != y.size())return x.size() < y.size();
	
	//在按照字典序的方式比较 
	return x<y;
}

//高精度减法模板 
void sub(int c[],int a[],int b[])
{
	for(int i = 0;i<lc;i++)
	{
		c[i] += a[i] - b[i];
		if(c[i] < 0)
		{
			c[i+1]-=1;//借位 
			c[i] += 10;
		}
	}
	//处理前导0 
	while(lc > 1 && c[lc-1]==0)lc--;
}

int main()
{
	string x,y;
	cin >> x >> y;
	
	//1.比大小
	if(cmp(x,y)) 
	{
		swap(x,y);
		cout << '-';
	}
	
	//2.拆分每一位,逆序放在数组中
	 la = x.size() ;lb = y.size() ;lc = max(la,lb);
	 for(int i = 0;i<la;i++) a[la-1-i] = x[i]-'0';
	 for(int i = 0;i<lb;i++) b[lb-1-i] = y[i]-'0';
	 
	 //3.模拟减法过程
	 sub(c,a,b); //c = a-b
	 
	 //4.输出结果
	 for(int i = lc-1;i>=0;i--)cout << c[i];
	 return 0; 
}

 

四、高精度乘法

P1303 A*B Problem - 洛谷

#include <iostream>
using namespace std;

const int N = 1e6 + 10;
int a[N],b[N],c[N];
int la,lb,lc;

void mul(int c[],int a[],int b[])
{
	//无进位相乘,然后相加 
	for(int i = 0;i<la;i++)
	{
		for(int j = 0;j<lb;j++)
		{
			c[i + j] += a[i]*b[j];
		}
	}
	//处理进位
	for(int i = 0;i<lc;i++)
	{
		c[i+1] += c[i]/10;
		c[i] %= 10;
	 } 
	 //处理前导零
	 while(lc > 1 && c[lc-1] == 0) lc--;
}

int main()
{
	string x,y;
	cin >> x >> y;
	
	//1.拆分每一位,逆序放在数组中 
	 la = x.size() ,lb = y.size() ,lc = la+lb;
	for(int i = 0;i<la;i++)a[la - 1 - i] = x[i] - '0';
	for(int i = 0;i<lb;i++)b[lb - 1 - i] = y[i] - '0';
	
	//2.模拟乘法的过程
	mul(c,a,b);//c = a*b
	
	//3.输出结果
	for(int i = lc-1;i>=0;i--)cout<< c[i]; 
	return 0;
}

五、高精度除法

P1480 A/B Problem - 洛谷

#include <iostream>
using namespace std;

typedef long long LL;
const int N = 1e6 + 10;
int a[N],b,c[N];
int la,lc;

//高精度/低精度 
void sub(int c[],int a[],int b)
{
	LL t = 0;//标记每次除完之后的余数 
	for(int i = la-1;i>=0;i--)
	{
		//计算当前的被除数
		t = t*10 + a[i];
		c[i] = t/b;
		t %= b;	
	}	
	//处理前导0
	while(lc > 1&& c[lc-1] == 0)lc--; 
}
int main()
{
	string x;
	cin >> x >> b;
	la = x.size() ;
	
	for(int i = 0;i<la;i++)a[la-1-i] = x[i]-'0';
	
	//模拟除法的过程
	lc = la;
	 sub(c,a,b);
	 
	 //输出
	 for(int i = lc-1;i>=0;i--)cout << c[i]; 
	return 0;
}

;