华为OD机试中的水仙花数题目是一个经典的编程问题。以下是对该题目的详细解析:
一、题目描述
所谓水仙花数,是指一个n位的正整数,其各位数字的n次方和等于该数本身。例如,153是一个3位数,且153=13+53+3^3,所以153是一个水仙花数。
二、输入描述
- 第一行输入一个整数n,表示一个n位的正整数,n在3到7之间(包含3和7)。
- 第二行输入一个整数m,表示需要返回第m个水仙花数。返回长度是n的第m个水仙花数,个数从0开始编号。
三、输出描述
返回长度是n的第m个水仙花数。个数从0开始编号。
若m大于水仙花数的个数,返回最后一个水仙花数和m的乘积。
若输入不合法,返回-1。
示例1
输入
3
0
输出
153
说明:
153是第一个水仙花数.
示例2
输入
9
1
输出
-1
说明
9超出范围
四、解题思路
- 打表法:由于水仙花数的数量有限,且n的范围在3到7之间,因此可以通过预先计算并存储所有可能的水仙花数,以便在查询时直接返回结果。这种方法称为打表法。
- 验证法:对于每个n位的数,遍历该范围内的所有数,并验证其是否为水仙花数。但这种方法在查询时需要实时计算,效率较低。
在实际考试中,推荐使用打表法,因为它可以大大提高查询效率。
五、打表法实现步骤
- 根据问题的定义,计算并存储所有3到7位的水仙花数。
- 当接收到查询时(即输入n和m),直接从预处理好的结果中进行查找。
- 如果m超出该位数水仙花数的数量,输出最后一个水仙花数乘以m。
- 否则,输出第m个水仙花数。
六、示例代码
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class DaffodilNumber {
/**
* 主函数,用于根据用户输入的位数n和序号m,输出第m个n位数的水仙花数
* 如果输入的位数n不在3到7之间,或者序号m为负数,则输出-1表示非法输入
* 如果序号m超出该位数水仙花数的数量,则输出该位数水仙花数中最大的数乘以m的结果
* 否则,输出对应位数和序号的水仙花数
*/
public static void main(String[] args) {
// 预先存储的水仙花数表
Map<Integer, int[]> table = new HashMap<>();
table.put(3, new int[]{153, 370, 371, 407});
table.put(4, new int[]{1634, 8208, 9474});
table.put(5, new int[]{54748, 92727, 93084});
table.put(6, new int[]{548834});
table.put(7, new int[]{1741725, 4210818, 9800817, 9926315});
// 创建扫描器获取用户输入
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
// 检查n是否在3到7之间,或者m是否为负数
if (n < 3 || n > 7 || m < 0) {
System.out.println(-1); // 非法输入
} else if (m >= table.get(n).length) {
// 如果m超出该位数水仙花数的数量,输出最后一个水仙花数乘以m
System.out.println((long)table.get(n)[table.get(n).length - 1] * m);
} else {
// 否则,输出第m个水仙花数
System.out.println(table.get(n)[m]);
}
// 关闭扫描器
scanner.close();
}
}
七、运行示例及解析
输入:
3
0
输入解析:
n = 3:表示需要查找 3 位数的水仙花数。m = 0:表示需要查找第 0 个(即第一个,从 0 开始编号)3 位数的水仙花数。
运行步骤:
-
读取输入:
Scanner读取到n = 3和m = 0。
-
输入合法性检查:
n在 3 到 7 之间,合法。m为 0,非负数,合法。
-
查找水仙花数:
- 根据
n = 3,从table中获取 3 位数的水仙花数数组:[153, 370, 371, 407]。 - 根据
m = 0,查找该数组中的第 0 个元素(数组索引从 0 开始)。 - 第 0 个元素是
153。
- 根据
-
输出结果:
- 打印
153。
- 打印
完整输出:
153
注意事项:
- 在这个特定的例子中,由于
m是从 0 开始编号的,所以第 0 个元素实际上是数组中的第一个元素。 - 如果
m的值超出了数组的长度(例如,对于 3 位数的水仙花数,如果m = 4),则程序会输出最后一个水仙花数乘以m的结果。但在这个例子中,m = 0是有效的,所以直接输出了第 0 个水仙花数153。 - 程序中使用了
long类型来确保在m超出数组长度时,乘法运算不会溢出。但在这个例子中,这个转换并不是必需的,因为m是一个有效的索引。
八、注意事项
- 在处理输入时,要确保输入的n和m在合法范围内。
- 在输出时,要注意数据类型转换,特别是当m超出水仙花数数量时,需要将最后一个水仙花数与m的乘积转换为长整型(long)以避免溢出。
- 在实际考试中,要注意代码的优化和可读性,以便在有限的时间内完成题目要求。
通过以上解析和示例代码,相信你可以更好地理解并解答华为OD机试中的水仙花数题目。


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



