B1017. A除以B (20')

本题要求计算A/B,其中A是不超过1000位的正整数,B是1位正整数。你需要输出商数Q和余数R,使得A = B * Q + R成立。


输入格式:


输入在1行中依次给出A和B,中间以1空格分隔。


输出格式:


在1行中依次输出Q和R,中间以1空格分隔。


输入样例:
123456789050987654321 7
输出样例:
17636684150141093474 3


解题思路:

这题为大整数除法,如果用Python做就很简单,c的话比较麻烦,需要模拟除法的运算过程。模拟完后就得到了答案商Q和余数R。

由于对c语言大整数没有了解,此处借鉴算法笔记(胡凡 编)P170 5.6大整数运算(文末附上)


#include <cstdio>
#include <cstring>

struct bign {
	int d[1010];	//数组用于存放大整数的数字 
	int len;	//大整数长度 
	bign() {
		memset(d, 0, sizeof(d));
		len = 0;
	}
};

//将字符串转换为逆序大整数 
bign change(char str[]) {
	bign a;
	a.len = strlen(str);
	for(int i = 0; i < a.len; i++) {
		a.d[i] = str[a.len - i - 1] - '0';
	}
	return a;
} 

//大整数除法 
bign divide(bign a, int b, int& r) {
	bign c;
	c.len = a.len;	//被除数的每一位和商的每一位一一对应
	for(int i = a.len - 1; i >= 0; i--) {	//从高位开始 
		r = r * 10 + a.d[i];	//和上一位遗留的语数组合 
		if(r < b) c.d[i] = 0;	//不够除,该位为0 
		else {	//够除 
			c.d[i] = r / b; //商 
			r = r % b;	//获得新的余数 
		}
	} 
	while(c.len - 1 >= 1 && c.d[c.len - 1] == 0)	c.len--;	//去除高位的0.同时至少保留一位最低位 
	return c;
} 

//打印大整数 
void print(bign a) {
	for(int i = a.len - 1; i >= 0; i--) {
		printf("%d", a.d[i]);
	}
} 

int main() {
	char str1[1010], str2[1010];
	int b, r = 0;	//定义除数和余数 
	scanf("%s %d", str1, &b);
	bign a = change(str1);	//将字符串转换为大整数 
	print(divide(a, b, r));	//打印Q 
	printf(" %d", r);	//打印余数 
	return 0;
} 

算法笔记(胡凡 编)5.6大整数运算























bign add(bign a, bign b) {
	bign c;
	int carry = 0;	//carry是进位
	for(int i = 0; i < a.len || i < b.len; i++) {	//以较长的为界限 
		int temp = a.d[i] + b.d[i] + carry;		//两个对应位与进位相加 
		c.d[c.len++] = temp % 10;	//个位数为该位结果 
		carry = temp / 10;	//十位数为新的进位 
	} 
	if(carry != 0) {	//如果最后进位不为0,则直接赋给结果的最高位 
		c.d[c.len++] = carry;
	} 
	return c;
}


















bign sub(bign a, bign b) {
	bign c;
	for(int i = 0; i < a.len || b.len; i++) {	//以较长的为界限 
		if(a.d[i] < b.d[i]) {	//如果不够减 
			a.d[i + 1]--;	//向高位借位 
			a.d[i] += 10;	//当前位加10 
		}
		c.d[c.len++] = a.d[i] - b.d[i];		//减法结果为当前位结果 
	}
	while(c.len - 1 >= 1 && c.d[c.len - 1] == 0) {
		c.len--;	//去除高位的0,同时至少保留一位最低位 
	}
	return c;
} 

























bign multi(bign a, bign b) {
	bign c;
	int carry = 0;	//进位 
	for(int i = 0; i < a.len; i++) {	
		int temp = a.d[i] * b + carry; 
		c.d[c.len++] = temp % 10;		//个位作为该位结果 
		carry = temp / 10;		//高位部分作为新的进位 
	}
	while(carry != 0) {		//和加法不一样,乘法的进位可能不止一位,因此使用while 
		c.d[c.len++] = carry % 10;	
		carry /= 10; 
	}
	return c;
} 


























bign divide(bign a, int b, int& r) {
	bign c;
	c.len = a.len;	//被除数的每一位和商的每一位是一一对应的,因此先令长度相等 
	for(int i = a.len - 1; i >= 0; i--) {	//从高位开始 
		r = r * 10 + a.d[i];	//和上一位遗留的余数组合 
		if(r < b) c.d[i] = 0;	//不够除,该位为0 
		else {	//够除 
			c.d[i] = r / b;		//商 
			r = r % b;	//获得新的余数 
		}
	}
	while(c.len - 1 >= 1 && c.d[c.len - 1] == 0) {
		c.len--;	//去除高位的0,同时至少保留一位最低位 
	}
	return c;
} 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值