「浙江理工大学ACM入队200题系列」问题 H: 零基础学C/C++18——三位数反转

2022-12-11,,,,

本题是浙江理工大学ACM入队200题第二套中的H题

我们先来看一下这题的题面.


由于是比较靠前的题目,这里插一句.各位新ACMer朋友们,请一定要养成仔细耐心看题的习惯,尤其是要利用好输入和输出样例.

样例相当于给你举了个具体的例子,可以帮助你更好的理解题目
样例会告诉你输入和输出的格式,你必须要在程序里以这样的格式输入和输出,否则会出问题
样例可以在你本地写完代码之后用作测试,来检查你的代码能否正常地运行(不过样例运行正确并不代表完全对了,可能输入其他的数据会出现别的问题)


题面

题目描述

输入1个3位数,分离出它的百位、十位和个位,反转后输出

输入

输入1个3位整数

输出

输出3位整数的反转数

样例输入

250

样例输出

052

提示

分离出各位数字可以用取余和除数

注意在C语言里,2个整数相乘除结果还是整数 比如8/3在C语言里结果是2

取余采用符号%

比如8%3的结果应该是2即8除以3后的余数


题目分析

想要倒序输出3位数,首先我们必须取出这个三位数中的各个位,而这题对于新朋友们来说最难的点可能是取出数字中的各个位了,不过好在仁慈的叶教给出了提示.

我们可以通过对10取余来得到当前数字的个位,对10整除取得当前数字去掉最后一位(即十进制位右移一位)后的数字:

(图片有错别字,左边"正数"应为"整数")

同理也可推出对100取余、对100整除等操作的效果,取n进制的某一位同样也可使用类似的操作完成.

所以对于这题我们只需要通过上述操作的组合取出各个位上的数字,再将其反过来输出即可.

取出各个位上的数字的局部参考代码如下:

	int a = n / 100; // 取出百位(如果实在不能直接理解,可看成先/10去掉个位变为两位数(如250->25),再/10去掉新的个位变为1位数(如25->2),这样就是百位了)
int b = n / 10 % 10; // 取出十位(先去/10掉个位(250->25),再取%10新的个位,即十位)
int c = n % 10; // 取出个位

常见错误思路

解决了上述的难点之后,有些朋友们就掉坑了.这题的一个坑点就出现在倒序输出上,不过好在可以直接通过样例输入发现这个问题.

这些朋友们的倒序输出的思路是这样的,既然我可以反着十进制的规则取出各个十进制位,那我也可以正着十进制的规则算出倒过来的数,于是他们写出了如下的代码(局部)

	int res = c * 100 + b * 10 + a; // 根据十进制的定义求出倒序后的十进制数

常见错误原因解析

这样写在数学上确实没什么大问题,但是注意看这里的输出样例,我们的程序需要实现的是250->052而不是250->52,也就是说在这道题里,不能通过算出倒序后的数这种方式来解决,因为对于一个数字而言,首位的0是会省略的(如果题目要求要没有首位0,那确实可以这么写,因题而异).

这里就体现出了仔细看输入和输出样例的重要性了吧!各位朋友们一定要仔细耐心看题哦!

解决方案

那怎么办呢,很简单鸭,直接一个一个数字输出不就好了嘛(本质是字符串拼接),局部参考代码如下:

	printf("%d%d%d", c, b, a); // 将三个位按逆序逐个输出

参考代码

下面给出了我自己做这道题时候的完整代码:

(仅作为参考,一定要自己写一下奥,作弊没意思,害人又害己)

#include <stdio.h>

int main()
{
int n;
scanf("%d", &n);
int a = n / 100; // 取出百位(如果实在不能直接理解,可看成先/10去掉个位变为两位数(如250->25),再/10去掉新的个位变为1位数(如25->2),这样就是百位了)
int b = n / 10 % 10; // 取出十位(先去/10掉个位(250->25),再取%10新的个位,即十位)
int c = n % 10; // 取出个位
printf("%d%d%d\n", c, b, a); // 将三个位按逆序逐个输出 return 0;
}

提高

循环出队

其实,在学了循环之后,这道题还可以利用循环逐个取出各个位上的数字.

这种思路的出发点便是%10可以取个位而同时/10可以去个位,所以我们可以通过一个while循环,不断取出个位再去掉个位,将操作前的十位不断移至个位,直到无位可移(即数变为0),此时所有位已经全部倒序取出,循环结束.

参考代码(局部):

	int n;
scanf("%d", &n);
do // 必须要用do-while,保证循环至少进行一次,以处理0(当然你用while然后单独加一个特判也是可以的)
{
printf("%d", n % 10); // 取出当前的个位
n /= 10; // 去掉当前已取出的个位,让前面的十位变成个位进行下一次循环中的操作
} while(n) // 即n != 0,n当前还有位未处理
printf("\n");

第4套的问题C是可以通过这种方式解决的(只需要在循环中加一个计数器即可判断位数),这题问的也相对比较多,建议收藏这篇题解,届时如果有问题可以回过来看此段内容,不单独发了.


字符串倒序输出

此外,在学了字符串之后,这道题的逐个取出各个十进制位再逆序完全可以依托字符串的特点,直接将输入作为字符串倒序输出即可解决,这里就只给出参考代码(局部)了,学过字符串的话应该可以立马理解的:

	char n[5]; // 注意字符串习惯性开大一点,防止'\0'溢出
scanf("%s", n); // 普普通通倒序输出字符串,注意别写成i++了
for(int i = strlen(s) - 1; i >=0 ; i--)
{
printf("%c", n[i]);
}
printf("\n");

第4套的问题C也可以通过这种方式解决(字符串的有效长度就是位数).

"正是我们每天反复做的事情,最终造就了我们,优秀不是一种行为,而是一种习惯" ---亚里士多德

这篇题解就到这里了,各位朋友如果有问题欢迎到acm成员群中提问哦!

「浙江理工大学ACM入队200题系列」问题 H: 零基础学C/C++18——三位数反转的相关教程结束。

《「浙江理工大学ACM入队200题系列」问题 H: 零基础学C/C++18——三位数反转.doc》

下载本文的Word格式文档,以方便收藏与打印。