C语言PAT刷题 - 1017 A除以B

本文介绍了一种处理大数除法的算法实现方法,针对A/B运算中A为不超过1000位的大整数,B为1位正整数的情况。通过使用字符数组存储大数,并采用逐位计算的方式求解商数Q和余数R。

作者的话:若有朋友复制代码去PAT试着运行遇到问题的:
1.可能是格式问题,可以先把从本站复制的代码粘贴到记事本,再把记事本里的代码复制,然后粘贴到PAT的代码区,提交本题回答,应该就可以了;
2.可能是注释原因,PAT有时候检测到注释会编译错误,所以可以先把注释删了,再进行提交回答。
3.可能是作者当初根据题目写出来的代码仍存在一些疏漏,而恰好当时的测试机制没那么完善,没检测出问题。后面测试机制有所更新,故出现问题,若有相关需要的可以评论区留言或私信作者,我看到的话会去再查一下疏漏之处,然后更新文章。

一、题目描述
本题要求计算 A/B,其中 A 是不超过 1000 位的正整数,B 是 1 位正整数。你需要输出商数 Q 和余数 R,使得 A=B×Q+R 成立。
输入格式:
输入在一行中依次给出 A 和 B,中间以 1 空格分隔。
输出格式:
在一行中依次输出 Q 和 R,中间以 1 空格分隔。
输入样例:
123456789050987654321 7
输出样例:
17636684150141093474 3

二、解题思路
读题:

本题要求计算 A / B,其中 A 是不超过 1000 位的正整数,B 是 1 位正整数。
你需要输出商数 Q 和余数 R,使得 A = B×Q + R 成立。
A的范围太大了,不能用整型变量存储,但我们可以定义字符数组来进行存储,每个元素存储一位数字。
思路:
1.定义需要的变量(实际解题时是先定义认为需要用到的变量,后面遇到问题需要新定义变量时再回到上头来定义新的变量),从键盘接收A,B;
2.设置循环,将A/B的过程分解:除数一位看一位,一位不够看两位。除到哪位商哪位,哪位不够零占位。每次除后要比较,余数要比除数小(如A=111,B=2。先让A的最高位a[0]除以B,也就是1/2,,此时1<2,要看2位,令11/2,商5余1,商的第一位就是5,余数是1,这里先将商的第一位5输出;这个余数再和被除数A的后一位一起看,是11,11/2商5余1,故商的第二位也是5,将商的第二位5输出;再往后看A已经没有位数了,所以循环结束,此时可以知道余数为1,由于商和余数的结果之间要加空格,所以先输出一个空格,再输出余数1.结果正好就是55 1。这其实也是我们列竖式计算时的计算过程,只是平时光在用,很少去描述这个过程,所以现在看起来有点陌生,但它恰恰是我们一直在用的除法计算的方法哦)。

三、具体实现
0.标准C源程序框架

#include <stdio.h>
int main()
{
	return 0;
}

1.定义需要的变量(实际解题时是先定义认为需要用到的变量,后面遇到问题需要新定义变量时再回到上头来定义新的变量),从键盘接收A,B;

	char a[1000] = {'\0'};//a存储被除数A
	int b, q=0, r=0;//b是除数,q是商,r是余数
	int i = 0;
	scanf("%s%d",&a, &b);

2.设置循环,将A/B的过程分解:除数一位看一位,一位不够看两位。除到哪位商哪位,哪位不够零占位。每次除后要比较,余数要比除数小(如A=111,B=2。先让A的最高位a[0]除以B,也就是1/2,,此时1<2,要看2位,令11/2,商5余1,商的第一位就是5,余数是1,这里先将商的第一位5输出;这个余数再和被除数A的后一位一起看,是11,11/2商5余1,故商的第二位也是5,将商的第二位5输出;再往后看A已经没有位数了,所以循环结束,此时可以知道余数为1,由于商和余数的结果之间要加空格,所以先输出一个空格,再输出余数1.结果正好就是55 1)。

	while (a[i] != '\0')
	{
		q = (10 * r + a[i] - '0') / b;
		if (a[1] == '\0') printf("%d", q);//如果a为1位数,直接输出商;反之,则多位数/1位数商一定为正数
		else if ((i == 0) && (q == 0));//若a[0]/q为0,这个0为商的第一位,整数第一位为0时不需要输出
		else          printf("%d", q);//其他情况,直接输出q的值
		r = (10 * r + a[i++] - '0') % b;
	}
	printf(" %d", r);

四、测试数据
1.题目输入输出用例
2.输入:11 2 输出:5 1
3.输入:1 2 输出:0 1
4.输入:0 2 输出:0 0

五、全部代码

#include <stdio.h>
int main()
{
	//本题要求计算 A / B,其中 A 是不超过 1000 位的正整数,B 是 1 位正整数。
	//你需要输出商数 Q 和余数 R,使得 A = B×Q + R 成立。

	//A的范围太大了,不能用整型变量存储,但我们可以定义字符数组来进行存储,每个元素存储一位数字。
	char a[1000] = {'\0'};//a存储被除数A
	int b, q=0, r=0;//b是除数,q是商,r是余数
	int i = 0;
	scanf("%s%d",&a, &b);
	//33333333333333  2
	while (a[i] != '\0')
	{
		q = (10 * r + a[i] - '0') / b;
		if (a[1] == '\0') printf("%d", q);//如果a为1位数,直接输出商;反之,则多位数/1位数商一定为正数
		else if ((i == 0) && (q == 0));//若a[0]/q为0,这个0为商的第一位,整数第一位为0时不需要输出
		else          printf("%d", q);//其他情况,直接输出q的值
		r = (10 * r + a[i++] - '0') % b;
	}
	printf(" %d", r);
	return 0;
}

六、优化代码
没改多少,把下面这段代码改一下能少写1行。

		if (a[1] == '\0') printf("%d", q);//如果a为1位数,直接输出商;反之,则多位数/1位数商一定为正数
		else if ((i == 0) && (q == 0));//若a[0]/q为0,这个0为商的第一位,整数第一位为0时不需要输出
		else          printf("%d", q);//其他情况,直接输出q的值

修改后:

if((i == 0) && (q == 0) && (a[1]!='\0'));
else            printf("%d", q);
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值