大家好啊,这里是Cyber Striver的博客。今天我继续为大家带来PAT乙级的题解。
目录
题目
题解
#include <stdio.h>
#include <string.h>
int main()
{
char str[1001]; //A至多有1000位,c最大的变量也不能容纳(数据溢出),所以想到数组/字符串/指针的做法
int B, Q, R, len, i;
scanf("%s %d", str, &B); // A=B*Q+R
len = strlen(str); //获取第一个“大数”的位数/长度
Q = (str[0] - '0') / B; //获取第一个数的商。
/*特殊的两种情况:
1.长度仅有一位时可直接得到总Q;
2.当长度大于1时,如果首位数字比除数还要小的话那么第一位就是输出0了,这样显然是不符合题目要求的,所以这样便不输出。
*/
if (len == 1 || (len > 1 && Q != 0))
printf("%d", Q);
R = (str[0] - '0') % B; //获取第一个数的余数。
/*从第二个数开始到整个字符串结束,模拟手动除法*/
for (i = 1; i < len; i++)
{
Q = ((R * 10) + str[i] - '0') / B; //获取商是 (余数*10 + 下一个数) / B.
printf("%d", Q); //每获取一个商就输出一次。
R = ((R * 10) + str[i] - '0') % B; //获取余数是 (余数*10 + 下一个数) % B.
}
printf(" %d", R); //输出最后的余数。
return 0;
}
思路
首先我们来看题目,很容易看出这道题的目的是写出一个程序完成大数字的运算。而对于我们C语言来说,在我的知识范围内目前没有可以存放一个1000位数字的变量类型,即使是范围最大的unsigned long long int 的最大值2^64-1也远远达不到,所以在这里我们要使用C语言中强大的指针功能。
其实这道题的思路挺简单,关键是你是否能对数字运算敏感。遇到一道题,从简单处考虑先考虑特殊情况:
1.长度仅有一位时可直接得到总Q;
2.当长度大于1时,如果首位数字比除数还要小的话那么第一位就是输出0了,这样显然是不符合题目要求的(首位不为0,因为题目说的A是正整数所以无论如何首位都不是0),所以这样便不输出。
然后,模拟我们平时自己的算除法的过程:只不过对于这么一个大数字,c无法将它作为一个整体来做除法,那么就可以通过一位一位的运算来得出结果。其中比较巧妙的地方就是你获取到了某一位的商就可以直接打印出去(虽然我们平时做除法的时候就是这样,但是我们用的是竖式运算法,现在将它公式化了可能有点稍微没有理解过来。)
当然,最后的余数,才是总数的余数。
经验总结
1. 64机上的C语言部分变量范围:
2. 直接打印的妙思想。
3.习惯的偏见的破除(除法的竖式运算法和公式法)。
本次博客到这里就结束了,如果你觉得我的文章还不错的话,请给我多多点赞评论哦!