机考E卷100分题 - 水仙花数 Ⅰ

题目描述

所谓水仙花数,是指一个n位的正整数,其各位数字的n次方和等于该数本身。

例如153是水仙花数,153是一个3位数,并且153 = 1^3 + 5^3 + 3^3。

输入描述

第一行输入一个整数n,表示一个n位的正整数。n在3到7之间,包含3和7。

第二行输入一个正整数m,表示需要返回第m个水仙花数。

输出描述

返回长度是n的第m个水仙花数。个数从0开始编号。

若m大于水仙花数的个数,返回最后一个水仙花数和m的乘积。

若输入不合法,返回-1。

示例1

输入

3
0
12

输出

153
1

说明

153是第一个水仙花数

示例2

输入

9
1
12

输出

-1
1

说明

9超出范围

解题思路

Java

import java.util.*;

public class Main {
     public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        
        // 输入n和m
        int n = sc.nextInt();
        int m = sc.nextInt();
        
        // 判断输入是否合法
        if (n < 3 || n > 7) {
            System.out.println("-1");
            return;
        }
        
        // 计算水仙花数的范围
        int start = (int) Math.pow(10, n - 1);
        int end = (int) Math.pow(10, n);
        
        // 存储水仙花数的列表
        List<Integer> narcissusList = new ArrayList<>();
        
        // 遍历范围内的数,判断是否为水仙花数并加入列表
        for (int i = start; i < end; i++) {
            if (isNarcissusNumber(i, n)) {
                narcissusList.add(i);
            }
        }
        
        // 获取水仙花数列表的长度
        int size = narcissusList.size();
        
        // 若列表为空,输出-1
        if (size == 0) {
            System.out.println("-1");
            return;
        }
        
        // 输出第m个水仙花数,若m大于列表长度,则输出最后一个水仙花数乘以m
        System.out.println(m >= size ? narcissusList.get(size - 1) : narcissusList.get(m));
    }
    
    // 判断一个数是否为水仙花数
    public static boolean isNarcissusNumber(int num, int n) {
        int sum = 0;
        String numStr = String.valueOf(num);
        
        // 计算各位数字的n次方和
        for (int i = 0; i < n; i++) {
            sum += Math.pow(Integer.parseInt(numStr.substring(i, i + 1)), n);
        }
        
        // 判断是否为水仙花数
        return sum == num;
    }
}

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758

Python


def isNarcissusNumber(num, n):
    sum = 0
    numStr = str(num)

    for i in range(n):
        sum += int(numStr[i]) ** n

    return sum == num
n = int(input())
m = int(input())

if n < 3 or n > 7:
    print("-1")
    exit()

start = 10 ** (n - 1)
end = 10 ** n

narcissusList = []

for i in range(start, end):
    if isNarcissusNumber(i, n):
        narcissusList.append(i)

size = len(narcissusList)

if size == 0:
    print("-1")
    exit()

print(narcissusList[size - 1] if m >= size else narcissusList[m])



1234567891011121314151617181920212223242526272829303132333435

JavaScript

const readline = require('readline');

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

rl.on('line', (n) => {
  rl.on('line', (m) => {
    n= parseInt(n);
    m= parseInt(m);
 // 判断输入是否合法
  if (n < 3 || n > 7) {
    console.log("-1");
    rl.close();
    return;
  }
  
  // 计算水仙花数的范围
  const start = Math.pow(10, n - 1);
  const end = Math.pow(10, n);
  
  // 存储水仙花数的列表
  const narcissusList = [];
  
  // 遍历范围内的数,判断是否为水仙花数并加入列表
  for (let i = start; i < end; i++) {
    if (isNarcissusNumber(i, n)) {
      narcissusList.push(i);
    }
  }
  
  // 获取水仙花数列表的长度
  const size = narcissusList.length;
  
  // 若列表为空,输出-1
  if (size === 0) {
    console.log("-1");
    rl.close();
    return;
  }
  
  // 输出第m个水仙花数,若m大于列表长度,则输出最后一个水仙花数乘以m
  console.log(m >= size ? narcissusList[size - 1] : narcissusList[m]);
  
  rl.close();
});
});
 

// 判断一个数是否为水仙花数
function isNarcissusNumber(num, n) {
  let sum = 0;
  const numStr = String(num);
  
  // 计算各位数字的n次方和
  for (let i = 0; i < n; i++) {
    sum += Math.pow(parseInt(numStr.substring(i, i + 1)), n);
  }
  
  // 判断是否为水仙花数
  return sum === num;
}

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364

C++

#include <iostream>
#include <vector>
#include <cmath>
using namespace std;

bool isNarcissusNumber(int num, int n) {
    int sum = 0;
    string numStr = to_string(num);
    
    for (int i = 0; i < n; i++) {
        sum += pow(stoi(numStr.substr(i, 1)), n);
    }
    
    return sum == num;
}

int main() {
    int n, m;
    cin >> n >> m;
    
    if (n < 3 || n > 7) {
        cout << "-1" << endl;
        return 0;
    }
    
    int start = pow(10, n - 1);
    int end = pow(10, n);
    
    vector<int> narcissusList;
    
    for (int i = start; i < end; i++) {
        if (isNarcissusNumber(i, n)) {
            narcissusList.push_back(i);
        }
    }
    
    int size = narcissusList.size();
    
    if (size == 0) {
        cout << "-1" << endl;
        return 0;
    }
    
    cout << (m >= size ? narcissusList[size - 1] : narcissusList[m]) << endl;
    
    return 0;
}

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748

C语言

#include <stdio.h>
#include <math.h>
#include <stdlib.h>

// 判断一个数是否为水仙花数的函数声明
int isNarcissusNumber(int num, int n);

int main() {
    int n, m;
    
    // 输入n和m
    if (scanf("%d %d", &n, &m) != 2) {
        printf("-1\n");
        return -1;
    }

    // 判断输入是否合法,n必须在3到7之间
    if (n < 3 || n > 7) {
        printf("-1\n");
        return -1;
    }
    
    // 计算n位数的范围
    int start = pow(10, n - 1); // n位数的起始值,例如3位数从100开始
    int end = pow(10, n);       // n位数的结束值,例如3位数到999结束

    // 存储水仙花数的数组,最大长度为end - start
    int narcissusList[end - start];
    int count = 0; // 用于记录找到的水仙花数数量

    // 遍历范围内的数,判断是否为水仙花数
    for (int i = start; i < end; i++) {
        if (isNarcissusNumber(i, n)) {
            narcissusList[count++] = i; // 将水仙花数加入数组
        }
    }

    // 若没有找到任何水仙花数,输出-1
    if (count == 0) {
        printf("-1\n");
        return 0;
    }

    // 判断m的值是否超出找到的水仙花数的数量
    if (m >= count) {
        // m大于或等于水仙花数的数量时,返回最后一个水仙花数乘以m
        printf("%ld\n", narcissusList[count - 1] * m);
    } else {
        // 否则,返回第m个水仙花数
        printf("%ld\n", narcissusList[m]);
    }

    return 0;
}

// 判断一个数是否为水仙花数
int isNarcissusNumber(int num, int n) {
    int sum = 0;          // 用于存储各位数字的n次方和
    int original_num = num; // 保留原始数值用于最后比较

    // 逐位提取数字并计算n次方和
    while (num > 0) {
        int digit = num % 10;           // 获取当前数的最后一位数字
        sum += pow(digit, n);           // 计算该数字的n次方并加到总和中
        num /= 10;                      // 移除最后一位数字,继续处理剩下的数字
    }

    // 若n次方和等于原始数值,则该数为水仙花数
    return sum == original_num;
}
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
#牛客创作赏金赛#

主要记录自己的刷题日常,学而时习之。

全部评论

相关推荐

刚刚做了华为Java机考,人是懵的。三道题两小时,每道题都看着不难都有思路结果写完过了测试一提交只有10%通过率,最后只有第一题提到了85%,最后算下来135分过不了150线,我愧对期待值拉满的HR,愧对我自己的复习。。。还是没刷够和基础不足,但至少把题目发这里大伙帮我解决一下这个遗憾吧。(不是,哥们。发现十拿九稳的主思路只能过10%,真得懵吧)第一题100:游客参观总时长问游乐园每天开放多久能招待所有游客。游乐园每一段时间能接受任意个数游客。每一行给一个游客的参观时长[1,5],[1,2],&nbsp;[10,11],输出总时长&nbsp;4+1=5.&nbsp;数值全在10^6以下。(确认输入无误)我一开始想做合并时间段最后算累加,结果Arraylist写下来边界判断什么的瞎闹连测试案例都过不了。三道题都写完之后回来检查,改了方法,求出参观时长的最大值,以它为长度建立空数组,再遍历游客时间插入1.最后数1,数到0就断掉算长度累加。通过率到了85%,但是给的反馈是测试用例运行错误,不是超时,我就只能继续检查下一题去了。(没想到后续检查没救得了我)第二题200:字符串集合求交集(这个是我最懵的,教教)(不需要检查输入)题目意思非常简单,给你输入几个字符串集合,{3(长度)&nbsp;123&nbsp;456&nbsp;789}第一个集合.{&nbsp;2&nbsp;456&nbsp;789}第二个集合。输出每个集合交集最大的集合和长度&nbsp;2&nbsp;2&nbsp;\n&nbsp;1&nbsp;2&nbsp;。字符串完全相等就是交集的元素。就这么简单。&nbsp;我Hashmap存集合的输入顺序,也就是集合的序号,value存的是字符串ArrayList。然后按总输出的值遍历这个输入顺序下标获取那个字符串集合,然后和另一个下标对应的字符串集合遍历。四层遍历求个相等的情况+1,记录最长值和最长集合序号。过了测试例以后提交,10%,还是答案错误不是超时,我人懵了,回来检查的时候也还是懵的。各路大神务必教教我这必须查相等的遍历为什么过了基础例子然后只能过10%的测试。有什么优化办法能既考虑边界值也能简化时长的?第三题300:摘水果也蛮直白的,给你个正方形地图,然后每个格子上是水果的数量,如果不能走就是-1.&nbsp;果农要从左上角走到右下角,只能向下或向右。走到右下角以后他再从右下角折回来走(没限制怎么走回来)到左上角,问你他能采摘的最大水果数量。这题我承认肯定是算法没想明白,漏了什么很关键的东西。(应该早点放弃检查的,很烦)这题我一开始想搞个递归往下找记录总数改变地图数字,然后往上找再递归找路最后加起来。但是写出来了向下找路然后发现这个找路和求最大值的路想做复原太诡异了,(现在想想完全可以找到路了记下来再找到最大值,很有可能能避免一些case)就放弃了递归投向动态规划。我累加了一次dp所有值抵达右下角以后,发现这个格子里的值正好是走下去走上来能拿到的最大值,想了一下应该也对,如果从左上角走不下来,那也不可能从那条路折回来,所有通路值加到最后应该就是答案。(难道说!是多个通路,只能取2条最大?!状态转移没这么简单才对!)状态转移方程就是等于非-1的左侧和上侧的格子的值相加再加上本来格子里的值。如果左上都是-1那我直接设为0.(难道该设为-1?复盘才发现槽点太多)(给地图加了一行一列全设为0,从1开始遍历到n。)往回走也不可能走这里。最后得分10%。求解!
牛客141057821号:我用python做的 第一道题记得leetcode有原题,先用开始参观时间sort一下然后指针遍历求set union 第二道题我python暴力解法全过。。 第三道题我是两遍dp,已从从左上到右下一次右下到左上,中间把第一次遍历走过的格子设成0就完了。 话说150是分数线吗?可以问下哪里的消息么
查看3道真题和解析 投递华为等公司10个岗位
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务