作者的话:若有朋友复制代码去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);
本文介绍了一种处理大数除法的算法实现方法,针对A/B运算中A为不超过1000位的大整数,B为1位正整数的情况。通过使用字符数组存储大数,并采用逐位计算的方式求解商数Q和余数R。

被折叠的 条评论
为什么被折叠?



