华为OD机试真题---水仙花数

华为OD机试中的水仙花数题目是一个经典的编程问题。以下是对该题目的详细解析:

一、题目描述

所谓水仙花数,是指一个n位的正整数,其各位数字的n次方和等于该数本身。例如,153是一个3位数,且153=13+53+3^3,所以153是一个水仙花数。

二、输入描述

  1. 第一行输入一个整数n,表示一个n位的正整数,n在3到7之间(包含3和7)。
  2. 第二行输入一个整数m,表示需要返回第m个水仙花数。返回长度是n的第m个水仙花数,个数从0开始编号。

三、输出描述

返回长度是n的第m个水仙花数。个数从0开始编号。
若m大于水仙花数的个数,返回最后一个水仙花数和m的乘积。
若输入不合法,返回-1。

示例1
输入
3
0
输出
153

说明:

153是第一个水仙花数.

示例2
输入
9
1
输出
-1
说明

9超出范围

四、解题思路

  1. 打表法:由于水仙花数的数量有限,且n的范围在3到7之间,因此可以通过预先计算并存储所有可能的水仙花数,以便在查询时直接返回结果。这种方法称为打表法。
  2. 验证法:对于每个n位的数,遍历该范围内的所有数,并验证其是否为水仙花数。但这种方法在查询时需要实时计算,效率较低。

在实际考试中,推荐使用打表法,因为它可以大大提高查询效率。

五、打表法实现步骤

  1. 根据问题的定义,计算并存储所有3到7位的水仙花数。
  2. 当接收到查询时(即输入n和m),直接从预处理好的结果中进行查找。
  3. 如果m超出该位数水仙花数的数量,输出最后一个水仙花数乘以m。
  4. 否则,输出第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 位数的水仙花数。
运行步骤:
  1. 读取输入

    • Scanner 读取到 n = 3m = 0
  2. 输入合法性检查

    • n 在 3 到 7 之间,合法。
    • m 为 0,非负数,合法。
  3. 查找水仙花数

    • 根据 n = 3,从 table 中获取 3 位数的水仙花数数组:[153, 370, 371, 407]
    • 根据 m = 0,查找该数组中的第 0 个元素(数组索引从 0 开始)。
    • 第 0 个元素是 153
  4. 输出结果

    • 打印 153
完整输出:
153
注意事项:
  • 在这个特定的例子中,由于 m 是从 0 开始编号的,所以第 0 个元素实际上是数组中的第一个元素。
  • 如果 m 的值超出了数组的长度(例如,对于 3 位数的水仙花数,如果 m = 4),则程序会输出最后一个水仙花数乘以 m 的结果。但在这个例子中,m = 0 是有效的,所以直接输出了第 0 个水仙花数 153
  • 程序中使用了 long 类型来确保在 m 超出数组长度时,乘法运算不会溢出。但在这个例子中,这个转换并不是必需的,因为 m 是一个有效的索引。

八、注意事项

  1. 在处理输入时,要确保输入的n和m在合法范围内。
  2. 在输出时,要注意数据类型转换,特别是当m超出水仙花数数量时,需要将最后一个水仙花数与m的乘积转换为长整型(long)以避免溢出。
  3. 在实际考试中,要注意代码的优化和可读性,以便在有限的时间内完成题目要求。

通过以上解析和示例代码,相信你可以更好地理解并解答华为OD机试中的水仙花数题目。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值