问题描述
Problem Description
春天是鲜花的季节,水仙花就是其中最迷人的代表,数学上有个水仙花数,他是这样定义的:
“水仙花数”是指一个三位数,它的各位数字的立方和等于其本身,比如:153=1^3+5^3+3^3。
现在要求输出所有在m和n范围内的水仙花数。
Input
输入数据有多组,每组占一行,包括两个整数m和n(100<=m<=n<=999)。
Output
对于每个测试实例,要求输出所有在给定范围内的水仙花数,就是说,输出的水仙花数必须大于等于m,并且小于等于n,如果有多个,则要求从小到大排列在一行内输出,之间用一个空格隔开;
如果给定的范围内不存在水仙花数,则输出no;
每个测试实例的输出占一行。
Sample Input
100 120
300 380
Sample Output
no
370 371
问题分析
Problem Analyse
本题是为C语言初学者提供的。
前置知识:条件判断语句的语法和循环语句语法
Algorithm Analyse
这里讨论给出一个整数n,如何判断它是否为水仙花数的算法。
而判断一组数只要在外面加层循环就可以了。
- sum ← 0(0 赋值给 sum)
- n ← m
- 判断n是否为0,不是则进入下一步,否则跳到第7步
- sum += (n % 10)3
- n /= 10
- 重复第3步
- m 等于 sum 则返回1,否则返回0
至于输出的问题,完全可以再加个变量c,初始为0,每输出一个水仙花数都自增一次c++。然后在c > 0时就在数字前输出一个空格。最后判断 c > 0就只输出一个回车,否则还要输出no。
算法实现
从前面的算法很容易写出判断数m是否为水仙花数的函数:
int sxh(int m) {
int sum = 0;
int n = m;
while (n) {
sum += (n % 10)*(n % 10)*(n % 10);
n /= 10;
}
return sum == m;
}
主函数直接调用就可以了。
int main(void) {
int n, m, c;
while (scanf("%d%d", &m, &n)) {
for (c = 0; m <= n; m++) {
if (sxh(m))
printf(c++ ? " %d": "%d", m);
}
puts(c ? "\n" : "no\n");
}
return 0;
}
测试几组数据,都是对的。就这样提交。你完全可以通过本题。
但如果你有心,你会发现。其实从1->1000之间,总共也只有5个水仙花数:1 153 370 371 407。我们重复计算的只是这4个数字而已。
因为本题的数据两仅100->999。但万一有一题数据两非常庞大。而结果有像这次一样如此少。我们又该怎么办呢?
像这样的题目,算法很简单就可以实现,但优化也许需要我们花点时间去做,我们可以采用一种快速的“作弊”的方法:直接打表提交!
在比赛的时候,也许没有太多时间让我们去研究一道题目的算法。这样我们在思考其他题目的时间也可以用电脑来自动生成结果。
然后用哈希的思想,对每个输入的数据对应输出结果就可以了。当然,这是最没技术含量,但也是绝路上最有效的一颗救命稻草!
我这里讲这么多只是想让大家了解,应付比赛的着数是很多的。切不要思维定式了。