社区讨论

80pts求调

P1932A+B A-B A*B A/B A%B Problem参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@m31f7ddy
此快照首次捕获于
2024/11/03 17:59
去年
此快照最后确认于
2025/11/04 15:26
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;

struct BigInteger {
	int len,num[100001];
	char sign;

	BigInteger() {
		len = 0;
		sign = '+';
		memset(num,0,sizeof(num));
	}

	//输入大整数
	void input() {
		char c[100001];

		cin >> c;				//输入大整数到字符数组
		len = strlen(c);		//求位数

		//处理负数
		if(c[0] == '-') {
			for(int i = 1; i < len; i++)		//负整数转换并逆置
				num[len - i - 1] = c[i] - '0';
			sign = '-';
			len--;
		} else 	//处理正数
			for(int i = 0; i < len; i++)		//正整数转换并逆置
				num[len - i - 1] = c[i] - '0';

		//消除前导零
		for(int i = len - 1; i > 0 && num[i] == 0; len--,i--);
	}

	//输出大整数
	void output() {
		if (sign == '-')
			cout << sign;
		for(int i = len - 1; i >= 0; i--)
			cout << num[i];
		cout << '\n';
	}

	BigInteger calculator(BigInteger a,char op,BigInteger b) {
		switch(op) {
			case '+':
				if(a.sign == '+' && b.sign == '+')
					add(a,b);
				else if(a.sign == '+' && b.sign == '-')
					sub1(a,b);
				else if(a.sign == '-' && b.sign == '+')
					sub1(b,a);
				else {
					sign = '-';
					a.sign = b.sign = '+';
					add(a,b);
				}
				break;
			case '-':
				if(a.sign == '+' && b.sign == '+')
					sub1(a,b);
				else if(a.sign == '+' && b.sign == '-') {
					b.sign = '+';
					add(a,b);
				} else if(a.sign == '-' && b.sign == '+') {
					sign = '-';
					a.sign = '+';
					add(a,b);
				} else {
					b.sign = '+';
					sub1(b,a);
				}
				break;
			case '*':
				if((a.len == 1 && a.num[0] == 0) || (b.len == 1 && b.num[0] == 0)) {
					len = 1;
					num[0] = 0;
					break;
				}
				if((a.sign == '+' && b.sign == '+') || (a.sign == '-' && b.sign == '-'))
					sign = '+';
				else
					sign = '-';
				mul(a,b);
				break;
			case '/':
				if(b.len == 1 && b.num[0] == 0) {
					cout << "DIVISION ZERO ERROR\n";
					exit(0);
				}
				if((a.len == 1 && a.num[0] == 0) || (b.len == 1 && b.num[0] == 0)) {
					len=1;
					num[0]=0;
					break;
				}
				if((a.sign == '+' && b.sign == '+') || (a.sign == '-' && b.sign == '-'))
					sign = '+';
				else
					sign = '-';
				return div1(a,b);
		}
		return a;
	}

	//小于(成立为真,否则为假)
	bool less_than(BigInteger a) {
		//不等长
		if(len != a.len)
			return len < a.len;

		//等长
		for(int i = len; i >= 1; i--)
			if(num[i] != a.num[i])
				return num[i] < a.num[i];

		//相等
		return false;
	}

	//竖式加:c=a+b
	void add(BigInteger a,BigInteger b) {
		len = a.len > b.len ? a.len : b.len;
		for(int i = 0; i < len; i++) {
			num[i] += a.num[i] + b.num[i];
			if(num[i] >= 10) {
				num[i + 1] = num[i + 1] + 1;
				num[i] = num[i] - 10;
			}
		}

		//进位判断
		if(num[len]!=0)
			len++;
	}

	//竖式减_比大小:c=a-b
	void sub1(BigInteger a, BigInteger b) {
		len = a.len > b.len ? a.len : b.len;

		bool LE = a.less_than(b);
		if( !LE )					//a>=b,差为正
			for(int i = 0; i < len; i++) {
				if(a.num[i] < b.num[i]) {	//借位
					a.num[i + 1]--;
					a.num[i] += 10;
				}
				num[i] = a.num[i] - b.num[i];
			}
		else {					//a<b,差为负
			sign = '-';
			for(int i = 0; i < len; i++) {
				if(b.num[i] < a.num[i]) {	//借位
					b.num[i + 1]--;
					b.num[i] += 10;
				}
				num[i] = b.num[i] - a.num[i];
			}
		}

		//判断差的位数:消除前导零
		for(int i = len - 1; i > 0 && num[i] == 0; len--, i--);
	}

	//竖式减_不比大小:c=a-b
	void sub2(BigInteger a, BigInteger b) {
		len = a.len>b.len ? a.len : b.len;

		//对应项相减
		for(int i = 0; i < len; i++)
			num[i] = a.num[i] - b.num[i];

		//消去前导零
		for(int i = len - 1; i > 0 && num[i] == 0; len--,i--);

		//判断正负:非零最高位为负则为负
		if(num[len - 1] < 0) {			//处理差为负的情况,所有位置乘负一
			sign = '-';
			for(int i = len - 1; i >= 0; i--)
				num[i] *= -1;
		}
		for(int i = 0; i < len; i++)		//若对应位为负,则按借位处理
			if(num[i] < 0) {
				num[i] += 10;
				num[i + 1] -= 1;
			}

		//消去前导零
		for(int i = len - 1; i > 0 && num[i] == 0; len--, i--);
	}

	//竖式加:c=a*b
	void mul(BigInteger a, BigInteger b) {
		//乘零
		if((a.len == 1 && a.num[0] == 0) || (b.len == 1 && b.num[0] == 0)) {
			len = 0;
			num[0] = 0;
			return ;
		}

		//a*b
		for(int i = 0; i < a.len; i++)
			for(int j = 0; j < b.len; j++) {
				num[i + j] += a.num[i] * b.num[j];
				num[i + j + 1] += num[i + j] / 10;
				num[i + j] = num[i + j] % 10;
			}

		//位数判断
		len = a.len + b.len;
		if(num[len - 1] == 0)
			len--;
	}

	//++计数
	void plusplus() {
		int i;
		num[0]++;
		for(i = 0; num[i] >= 10; i++) {		//个位存储在 0下标计数
			num[i + 1] = num[i + 1] + 1;
			num[i] = num[i] - 10;
		}

		//进位判断
		if(i == len)
			len++;
	}

	//连续减实现除:c = a ÷b	返回值为余数
	BigInteger div1(BigInteger a, BigInteger b) {
		//对商清零
		len = 1;
		memset(num,0,sizeof(num));
		if(a.less_than(b))		//a<b时商为0,余数为a
			return a;

		//商为a能减几个b
		while( !a.less_than(b) ) {		//若a>=b则持续减
			a.sub2(a,b);
			plusplus();
			//a.output();
		}
		return a;
	}

	//移位操作,相当于乘10(基数)
	void leftshift(int count) {
		if(count == 0)			//防止无效移位
			return;

		for(int i = len - 1; i >= 0; i--)
			num[i + count] = num[i];
		for(int i = count - 1; i >= 0; i--)
			num[i] = 0;
		len += count;
		return ;
	}

	//补零减实现除:c = a ÷b	返回值为余数
	BigInteger div2(BigInteger a, BigInteger b) {
		//对商清零
		len = 1;
		memset(num, 0, sizeof(num));
		if(a.less_than(b))		//a<b时商为0,余数为a
			return a;

		len = a.len - b.len + 1;				//商最大位数
		BigInteger t = b;
		for(int i = len - 1; i >= 0; i--) {	//i为补零个数
			t.leftshift(i);
			while( !a.less_than(t) ) {
				a.sub1(a, t);
				num[i]++;
			}
			t=b;
			//a.output();
			//cout << " " << num[i] << '/n';
		}
		while( num[len-1] == 0 )
			len--;

		return a;
	}
} x, y, a, s, m, d, rem;

int main() {
	//输入大整数
	x.input();
	y.input();
	
	a.calculator(x, '+', y);
	s.calculator(x, '-', y);
	m.calculator(x, '*', y);
	d.calculator(x, '/', y);
    rem = d.calculator(x, '/', y);
		
    a.output();
    s.output();
    m.output();
    d.output();
    rem.output();
    return 0;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...