Part 2.7 高精度

在 C++ 中,long long 都无法表示我们需要的整数时怎么办?那就用高精度吧!

A+B Problem(高精)

题目描述

高精度加法,相当于 a+b problem,不用考虑负数

输入格式

分两行输入。 a , b ≤ 1 0 500 a,b \leq 10^{500} a,b10500

输出格式

输出只有一行,代表 a + b a+b a+b 的值。

样例 #1

样例输入 #1

1
1

样例输出 #1

2

样例 #2

样例输入 #2

1001
9099

样例输出 #2

10100

提示

20 % 20\% 20% 的测试数据, 0 ≤ a , b ≤ 1 0 9 0\le a,b \le10^9 0a,b109

40 % 40\% 40% 的测试数据, 0 ≤ a , b ≤ 1 0 18 0\le a,b \le10^{18} 0a,b1018

代码实现

#include<iostream>
#include<vector>
#include<string>
using namespace std;
class BigInt:public vector<int> 
{
	public:
		BigInt(){push_back(0);}
		BigInt(string s)
		{
			for(int i=s.size()-1;i>=0;i--)push_back(s[i]-'0');
			proccess_digit();
		}
		BigInt&operator+=(const BigInt&a)
		{
			for(int i=0;i<a.size();i++)
			{
				if(i>=size())push_back(0);
				at(i)+=a[i];
			}
			proccess_digit();
			return *this;
		}
		void proccess_digit()
		{
			for(int i=0;i<size();i++)
			{
				if(at(i)<10)continue;
				if(i==size()-1)push_back(0);
				at(i+1)+=at(i)/10;
				at(i)%=10;
			}
			return ;
		}		
};
ostream&operator<<(ostream&out,BigInt&a)
{
	for(int i=a.size()-1;i>=0;i--)
	out<<a[i];
	return out;
}
int main()
{
	string s;
	cin>>s;
	BigInt a(s);
	cin>>s;
	BigInt b(s);
	a+=b;
	cout<<a;
	return 0;
}


高精度减法

题目描述

高精度减法。

输入格式

两个整数 a , b a,b a,b(第二个可能比第一个大)。

输出格式

结果(是负数要输出负号)。

样例 #1

样例输入 #1

2
1

样例输出 #1

1

提示

  • 20 % 20\% 20% 数据 a , b a,b a,b 在 long long 范围内;
  • 100 % 100\% 100% 数据 0 < a , b ≤ 1 0 10086 0<a,b\le 10^{10086} 0<a,b1010086

代码实现

#include<iostream>
#include<vector>
#include<string>
using namespace std;
class BigInt:public vector<int>
{
	public:
		BigInt(){push_back(0);}
		BigInt(string s){
			for(int i=s.size()-1;i>=0;i--)
			push_back(s[i]-'0');
		}
		BigInt&operator-=(BigInt&a)
		{
			for(int i=0;i<a.size();i++)
			at(i)-=a[i];
			proccess_digit();
			return *this;
		}
		void proccess_digit()
		{
			for(int i=0;i<size();i++)
			{
				if(at(i)>=0)continue;
				at(i+1)-=1;
				at(i)+=10;
			}
			return ;
		}
};
bool compare(const BigInt&a,const BigInt&b)
{
	if(a.size()!=b.size())return a.size()>b.size();
	else{
		for(int i=a.size()-1;i>=0;i--)
		{
			if(a[i]>b[i])return 1;
			if(a[i]<b[i])return 0;
		}
	}
	return 1;
}
ostream&operator<<(ostream&out,BigInt a)
{
	int flag=1;
	for(int i=a.size()-1;i>=0;i--)
	{
		if(flag&&!a[i])continue;
		out<<a[i];
		flag=0;
	}
	if(flag)cout<<0;
	return out;
}
int main()
{
	string s;
	cin>>s;
	BigInt a(s);
	cin>>s;
	BigInt b(s);
	if(compare(a,b))
	{
		a-=b;
		cout<<a;
	}
	else{
		cout<<'-';
		b-=a;
		cout<<b;
	}
	return 0;
}

A*B Problem

题目背景

高精度乘法模板题。

题目描述

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

输入格式

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

输出格式

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

样例 #1

样例输入 #1

1 
2

样例输出 #1

2

提示

每个非负整数不超过 1 0 2000 10^{2000} 102000

#include<iostream>
#include<vector>
#include<string>
using namespace std;
class BigInt:public vector<int>
{
	public:
		BigInt(){push_back(0);}
		BigInt(string s){
			for(int i=s.size()-1;i>=0;i--)
			push_back(s[i]-'0');
		}
		BigInt operator*(const BigInt&a)
		{
			BigInt c;
			for(int i=0;i<size();i++)
			{
				for(int j=0;j<a.size();j++)
				{
					if(i+j>=c.size())c.push_back(0);
					c.at(i+j)+=at(i)*a[j];
				}
			}
			c.proccess_digit();
			return c;
		}
		
		BigInt&operator=(const BigInt&a)
		{
			for(int i=0;i<a.size();i++)
			{
				if(i>=size())push_back(0);
				at(i)=a[i];
			}
			for(int i=a.size();i<size();i++)erase(begin()+i);
			return *this;
		}
		BigInt&operator*=(const BigInt&a)
		{
			*this=(*this)*a;
			return *this;
		}
		void proccess_digit()
		{
			for(int i=0;i<size();i++)
			{
				if(at(i)<10)continue;
				if(i==size()-1)push_back(0);
				at(i+1)+=at(i)/10;
				at(i)%=10;
			}
			return ;
		}
};
ostream&operator<<(ostream&out,BigInt&a)
{
	int flag=1;
	for(int i=a.size()-1;i>=0;i--)
	{
		if(flag&&!a[i])continue;
		out<<a[i];
		flag=0;
	}
	if(flag)out<<0;
	return out;
}
int main()
{ 
	string s;
	cin>>s;
	BigInt a(s);
	cin>>s;
	BigInt b(s);
	a*=b;
	cout<<a;
	return 0;
}

A/B Problem

题目描述

输入两个整数 a , b a,b a,b,输出它们的商。

输入格式

两行,第一行是被除数,第二行是除数。

输出格式

一行,商的整数部分。

样例 #1

样例输入 #1

10
2

样例输出 #1

5

提示

0 ≤ a ≤ 1 0 5000 0\le a\le 10^{5000} 0a105000 1 ≤ b ≤ 1 0 9 1\le b\le 10^9 1b109

代码实现

#include<iostream>
#include<vector>
#include<string>
using namespace std;
class BigInt:public vector<int>
{
	public:
		BigInt(){push_back(0);}
		BigInt(string s){
			for(int i=s.size()-1;i>=0;i--)
			push_back(s[i]-'0');
		}
		BigInt operator/(int x)
		{
			BigInt ret(*this);
			long long now=0;
			for(int i=size()-1;i>=0;i--)
			{
				now=10*now+at(i);
				ret[i]=now/x;
				now%=x;
			}
			return ret;
		}
		BigInt&operator/=(int x)
		{
			*this=(*this)/x;
			return *this;
		}
}; 
ostream&operator<<(ostream&out,BigInt&a)
{
	int flag=1;
	for(int i=a.size()-1;i>=0;i--)
	{
		if(flag&&!a[i])continue;
		out<<a[i];
		flag=0;
	}
	if(flag)out<<0;
	return out;
}
int main()
{
	string s;
	int b;
	cin>>s;
	BigInt a(s);
	cin>>b;
	a/=b;
	cout<<a;
	return 0;
} 

[NOIP1998 普及组] 阶乘之和

题目描述

用高精度计算出 S = 1 ! + 2 ! + 3 ! + ⋯ + n ! S = 1! + 2! + 3! + \cdots + n! S=1!+2!+3!++n! n ≤ 50 n \le 50 n50)。

其中 ! 表示阶乘,定义为 n ! = n × ( n − 1 ) × ( n − 2 ) × ⋯ × 1 n!=n\times (n-1)\times (n-2)\times \cdots \times 1 n!=n×(n1)×(n2)××1。例如, 5 ! = 5 × 4 × 3 × 2 × 1 = 120 5! = 5 \times 4 \times 3 \times 2 \times 1=120 5!=5×4×3×2×1=120

输入格式

一个正整数 n n n

输出格式

一个正整数 S S S,表示计算结果。

样例 #1

样例输入 #1

3

样例输出 #1

9

提示

【数据范围】

对于 100 % 100 \% 100% 的数据, 1 ≤ n ≤ 50 1 \le n \le 50 1n50

【其他说明】

注,《深入浅出基础篇》中使用本题作为例题,但是其数据范围只有 n ≤ 20 n \le 20 n20,使用书中的代码无法通过本题。

如果希望通过本题,请继续学习第八章高精度的知识。

NOIP1998 普及组 第二题

代码实现

#include<iostream>
#include<vector>
#include<string>
using namespace std;
class BigInt:public vector<int>
{
	public:
		BigInt(){push_back(0);}
		BigInt(string s){
			for(int i=s.size()-1;i>=0;i--)
			push_back(s[i]-'0');
		}
		BigInt&operator+=(const BigInt&a)
		{
			for(int i=0;i<a.size();i++)
			{
				if(i>=size())push_back(0);
				at(i)+=a[i];
			}
			proccess_digit();
			return *this;
		}
		BigInt&operator*=(int a)
		{
			for(int i=0;i<size();i++)
			at(i)*=a;
			proccess_digit();
			return *this;
		}
		void proccess_digit()
		{
			for(int i=0;i<size();i++)
			{
				if(at(i)<10)continue;
				if(i==size()-1)push_back(0);
				at(i+1)+=at(i)/10;
				at(i)%=10;
			}
			return ;
		}
};
ostream&operator<<(ostream&out,BigInt&a)
{
	int flag=1;
	for(int i=a.size()-1;i>=0;i--)
	{
		if(flag&&!a[i])continue;
		out<<a[i];
		flag=0;
	}
	if(flag)out<<0;
	return out;
}
int main()
{ 
	int n;
	cin>>n;
	string a="1";
	BigInt ans,t(a);
	for(int i=1;i<=n;i++)
	{
		t*=i;
		ans+=t;
	}
	cout<<ans;
	return 0;
}
  • 33
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值