高精度算法-例题篇

一、(洛谷P1601)A+B problem(高精)

#include 
using namespace std;
#include 
#include 
#define maxn 505
struct Bigint {
	//定义位数和数位
	int len, a[maxn];
	//初始化,使得大整数能够表示整型x,默认为0
	Bigint(int x = 0) {
		memset(a, 0, sizeof(a));
		for (len = 1; x; len++) {
			a[len] = x % 10;
			x /= 10;
		}
		len--;
	}
	//重载[],可以直接使用x[i]代表x.a[i],编写时更自然
	int& operator[](int i) {
		return a[i];
	}
	//一口气处理1到L范围内的进位并重置长度,需要保证L不小于有效长度
	void flatten(int L) {
		len = L;
		for (int i = 1; i <= len; i++) {
			a[i + 1] += a[i] / 10;
			a[i] %= 10;
		}
		for (; !a[len];) len--;
	}
	//输出
	void print() {
		for (int i = max(1, len); i >= 1; i--) {
			printf("%d", a[i]);
		}
	}
};
//高精+高精
Bigint operator+(Bigint a,Bigint b) {
	Bigint c;
	int len = max(a.len, b.len);
	for (int i = 1; i <= len; i++) {
		c[i] += a[i] + b[i];
	}
	c.flatten(len + 1);
	return c;
}
//高精*低精
Bigint operator*(Bigint a, int b) {
	Bigint c;
	int len = a.len;
	for (int i = 1; i <= len; i++) {
		c[i] = a[i] * b;
	}
	c.flatten(len + 11);
	return c;
}
//高精*高精
Bigint operator*(Bigint a, Bigint b) {
	Bigint c;
	int len = a.len + b.len-1;
	for (int i = 1; i <= a.len; i++) {
		for (int j = 1; j <= b.len; j++) {
			c[i + j - 1] += a[i] * b[j];
		}
	}
	c.flatten(len + 1);
	return c;
}
int a1[maxn], b1[maxn];
 int main() {
	string a, b;
	cin >> a >> b;
	Bigint m;
	for (int i = a.length() - 1; i >= 0; i--) a1[a.length() - i] = a[i] - '0';
	for (int i = b.length() - 1; i >= 0; i--) b1[b.length() - i] = b[i] - '0';
	for (int i = 1; i <= a.length(); i++) {
		m[i] = a1[i];
		m.len = a.length();
	}
	Bigint n;
	for (int i = 1; i <= b.length(); i++) {
		n[i] = b1[i];
		n.len = b.length();
	}
	Bigint sum = m + n;
	sum.print();
	return 0;
}

二、(洛谷P1303)A*B problem

#include 
using namespace std;
#include 
#include 
#define maxn 2005
struct Bigint {
	//定义位数和数位
	int len, a[maxn*2];
	//初始化,使得大整数能够表示整型x,默认为0
	Bigint(int x = 0) {
		memset(a, 0, sizeof(a));
		for (len = 1; x; len++) {
			a[len] = x % 10;
			x /= 10;
		}
		len--;
	}
	//重载[],可以直接使用x[i]代表x.a[i],编写时更自然
	int& operator[](int i) {
		return a[i];
	}
	//一口气处理1到L范围内的进位并重置长度,需要保证L不小于有效长度
	void flatten(int L) {
		len = L;
		for (int i = 1; i <= len; i++) {
			a[i + 1] += a[i] / 10;
			a[i] %= 10;
		}
		for (; !a[len];) len--;
	}
	//输出
	void print() {
		for (int i = max(1, len); i >= 1; i--) {
			printf("%d", a[i]);
		}
	}
};
//高精+高精
Bigint operator+(Bigint a,Bigint b) {
	Bigint c;
	int len = max(a.len, b.len);
	for (int i = 1; i <= len; i++) {
		c[i] += a[i] + b[i];
	}
	c.flatten(len + 1);
	return c;
}
//高精*低精
Bigint operator*(Bigint a, int b) {
	Bigint c;
	int len = a.len;
	for (int i = 1; i <= len; i++) {
		c[i] = a[i] * b;
	}
	c.flatten(len + 11);
	return c;
}
//高精*高精
Bigint operator*(Bigint a, Bigint b) {
	Bigint c;
	int len = a.len + b.len-1;
	for (int i = 1; i <= a.len; i++) {
		for (int j = 1; j <= b.len; j++) {
			c[i + j - 1] += a[i] * b[j];
		}
	}
	c.flatten(len + 1);
	return c;
}
int a1[maxn], b1[maxn];
 int main() {
	string a, b;
	cin >> a >> b;
	Bigint m;
	for (int i = a.length() - 1; i >= 0; i--) a1[a.length() - i] = a[i] - '0';
	for (int i = b.length() - 1; i >= 0; i--) b1[b.length() - i] = b[i] - '0';
	for (int i = 1; i <= a.length(); i++) {
		m[i] = a1[i];
		m.len = a.length();
	}
	Bigint n;
	for (int i = 1; i <= b.length(); i++) {
		n[i] = b1[i];
		n.len = b.length();
	}
	Bigint sum = m * n;
	sum.print();
	return 0;
}

三、(洛谷P1009)阶乘之和

#include 
using namespace std;
#include 
#include 
#define maxn 105
struct Bigint {
	//定义位数和数位
	int len, a[maxn];
	//初始化,使得大整数能够表示整型x,默认为0
	Bigint(int x = 0) {
		memset(a, 0, sizeof(a));
		for (len = 1; x; len++) {
			a[len] = x % 10;
			x /= 10;
		}
		len--;
	}
	//重载[],可以直接使用x[i]代表x.a[i],编写时更自然
	int& operator[](int i) {
		return a[i];
	}
	//一口气处理1到L范围内的进位并重置长度,需要保证L不小于有效长度
	void flatten(int L) {
		len = L;
		for (int i = 1; i <= len; i++) {
			a[i + 1] += a[i] / 10;
			a[i] %= 10;
		}
		for (; !a[len];) len--;
	}
	//输出
	void print() {
		for (int i = max(1, len); i >= 1; i--) {
			printf("%d", a[i]);
		}
	}
};
//高精+高精
Bigint operator+(Bigint a,Bigint b) {
	Bigint c;
	int len = max(a.len, b.len);
	for (int i = 1; i <= len; i++) {
		c[i] += a[i] + b[i];
	}
	c.flatten(len + 1);
	return c;
}
//高精*低精
Bigint operator*(Bigint a, int b) {
	Bigint c;
	int len = a.len;
	for (int i = 1; i <= len; i++) {
		c[i] = a[i] * b;
	}
	c.flatten(len + 11);
	return c;
}
//高精*高精
Bigint operator*(Bigint a, Bigint b) {
	Bigint c;
	int len = a.len + b.len-1;
	for (int i = 1; i <= a.len; i++) {
		for (int j = 1; j <= b.len; j++) {
			c[i + j - 1] += a[i] * b[j];
		}
	}
	c.flatten(len + 1);
	return c;
}
 int main() {
	 Bigint ans(0), fac(1);
	 int m;
	 cin >> m;
	 for (int i = 1; i <= m; i++) {
		 fac = fac * i;
		 ans = ans + fac;
	 }
	 ans.print();
	return 0;
}

四、(洛谷P2142)A-B高精度减法

#include 
#include 
#include 
using namespace std;
int A[10100],B[10100],C[10100];
int main() {
	string a, b;
	cin >> a >> b;
	if ((a.length() == b.length() && a < b )|| a.length() < b.length()) {
		swap(a, b);
		cout << '-';
	}
	for (int i = a.length() - 1,j=1; i >=0; i--,j++) {
		A[j] = a[i] - '0';
	}
	for (int i = b.length() - 1, j = 1; i >= 0; i--, j++) {
		B[j] = b[i] - '0';
	}
	int len = max(a.length(), b.length());
	for (int j = 1; j <= len; j++){
		if (A[j] >= B[j]) C[j] = A[j] - B[j];
		else {
			C[j] = A[j] + 10 - B[j];
			A[j + 1]--;
		}
	}
	while (C[len] == 0&&len>1) len--;
	for (int k = len; k >= 1; k--) {
		cout << C[k];
	}
	return 0;
}

总结:

高精+高精

高精+低精

高精*低精

高精*高精

高精-高精

(高精-低精)

你可能感兴趣的:(数据结构与算法,算法)