华为OD机试 - 水仙花数Ⅱ - 动态规划(Python/JS/C/C++ 2024 E卷 200分)

news2024/9/22 0:48:36

在这里插入图片描述

华为OD机试 2024E卷题库疯狂收录中,刷题点这里

专栏导读

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

一、题目描述

给定非空字符串S,将该字符串分割成一些子串,使每个子串的ASCII码值的和均为水仙花数。

若分割不成功,则返回0;

若分割成功且分割结果不唯一,则返回-1;

若分割成功且分割结果唯一,则返回分割后子串的数目。

二、输入描述

输入字符串的最大长度为200

三、输出描述

根据题目描述中的情况,返回相应的结果。

四、测试用例

测试用例1:

1、输入

f3@d5a8

2、输出

-1

3、说明

分割成功但分割结果不唯一,可以分割为两组,一组f3和@d5a8,另外一组f3@d5和a8。

测试用例2:

1、输入

AXY

2、输出

0

3、说明

字符串 AXY 可以有两种划分方式:

方案1:AX 和 Y,其ASCII和分别为153和89。153 是水仙花数,但89不是。

方案2:AXY 整体的ASCII和为 234,不是水仙花数。

无法划分为符合要求的子串,因此不能分割成功。

返回 0。

五、解题思路

这道题要求将字符串分割成若干子串,并且每个子串的ASCII码值的和必须是水仙花数。水仙花数是指一个三位数,每一位的立方和等于该数本身。

解题步骤:

  1. 水仙花数的判定:首先生成所有水仙花数(100到999之间的数字),并存入一个集合中以便后续快速查找。
  2. ASCII值和计算:遍历字符串,尝试将字符串划分为多个子串,计算每个子串的ASCII值之和,判断这些和是否为水仙花数。
  3. 动态规划求解:
    • 使用动态规划的思想来解决这个问题。定义一个数组dp[i],表示到索引i为止的字符串是否可以被划分,并且记录不同划分方案的数量。
    • 初始化dp[0] = 1,表示空字符串可以被划分。
    • 遍历字符串并尝试从每个位置开始到下一个位置,判断该子串的ASCII值之和是否为水仙花数,如果是,则更新dp数组。
  4. 结果判断:根据最终的dp值来判断结果:
    • 若字符串不能被划分为符合条件的子串,则返回0。
    • 若存在多个划分方案,则返回-1。
    • 若唯一划分方案成功,则返回子串的数量。

六、Python算法源码

def generate_narcissistic_numbers():
    # 生成所有的水仙花数
    narcissistic_numbers = set()
    for i in range(100, 1000):
        hundred = i // 100
        ten = (i // 10) % 10
        one = i % 10
        if i == hundred ** 3 + ten ** 3 + one ** 3:
            narcissistic_numbers.add(i)
    return narcissistic_numbers

def get_ascii_sum(s, start, end):
    # 计算子串的ASCII和
    return sum(ord(s[i]) for i in range(start, end))

def partition_string(s):
    n = len(s)
    narcissistic_numbers = generate_narcissistic_numbers()  # 获取所有水仙花数
    dp = [0] * (n + 1)
    ways = [0] * (n + 1)  # 记录不同的划分方案数

    dp[0] = 1  # 空字符串可以被划分
    ways[0] = 1  # 初始只有一种划分方式

    for i in range(1, n + 1):
        dp[i] = 0  # 初始化不可划分状态
        for j in range(i):
            sum_ascii = get_ascii_sum(s, j, i)  # 计算从j到i的子串的ASCII和
            if sum_ascii in narcissistic_numbers:  # 如果子串的ASCII和是水仙花数
                if dp[j] == 1:
                    dp[i] = 1
                    ways[i] += ways[j]  # 更新到i位置的划分方式数量

    if dp[n] == 0:
        return 0  # 如果无法划分,返回0
    elif ways[n] > 1:
        return -1  # 如果有多种划分方式,返回-1
    else:
        return dp[n]  # 返回唯一划分方案的子串数量

def main():
    # 从控制台读取输入
    input_string = input("请输入字符串: ")  # 从控制台读取输入的字符串

    # 调用partition_string方法计算结果
    result = partition_string(input_string)

    # 输出结果
    print(result)

if __name__ == "__main__":
    main()

七、JavaScript算法源码

// 生成所有水仙花数
function generateNarcissisticNumbers() {
    const narcissisticNumbers = new Set();
    for (let i = 100; i <= 999; i++) {
        const hundred = Math.floor(i / 100);
        const ten = Math.floor((i / 10) % 10);
        const one = i % 10;
        if (i === hundred ** 3 + ten ** 3 + one ** 3) {
            narcissisticNumbers.add(i);
        }
    }
    return narcissisticNumbers;
}

// 计算子串的ASCII和
function getASCIISum(s, start, end) {
    let sum = 0;
    for (let i = start; i < end; i++) {
        sum += s.charCodeAt(i);
    }
    return sum;
}

function partitionString(s) {
    const n = s.length;
    const narcissisticNumbers = generateNarcissisticNumbers(); // 获取所有水仙花数
    const dp = new Array(n + 1).fill(0);
    const ways = new Array(n + 1).fill(0); // 记录不同的划分方案数

    dp[0] = 1;  // 空字符串可以被划分
    ways[0] = 1;  // 初始只有一种划分方式

    for (let i = 1; i <= n; i++) {
        dp[i] = 0;  // 初始化不可划分状态
        for (let j = 0; j < i; j++) {
            const sum = getASCIISum(s, j, i);  // 计算从j到i的子串的ASCII和
            if (narcissisticNumbers.has(sum)) {  // 如果子串的ASCII和是水仙花数
                if (dp[j] === 1) {
                    dp[i] = 1;
                    ways[i] += ways[j];  // 更新到i位置的划分方式数量
                }
            }
        }
    }

    if (dp[n] === 0) {
        return 0;  // 如果无法划分,返回0
    } else if (ways[n] > 1) {
        return -1;  // 如果有多种划分方式,返回-1
    } else {
        return dp[n];  // 返回唯一划分方案的子串数量
    }
}

function main() {
    // 从控制台读取输入
    const input = prompt("请输入字符串: ");  // 从控制台读取输入的字符串

    // 调用partitionString方法计算结果
    const result = partitionString(input);

    // 输出结果
    console.log(result);
}

main();

八、C算法源码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

// 生成所有水仙花数
void generateNarcissisticNumbers(bool narcissisticNumbers[1000]) {
    for (int i = 100; i <= 999; i++) {
        int hundred = i / 100;
        int ten = (i / 10) % 10;
        int one = i % 10;
        if (i == hundred * hundred * hundred + ten * ten * ten + one * one * one) {
            narcissisticNumbers[i] = true;
        }
    }
}

// 计算子串的ASCII和
int getASCIISum(const char* s, int start, int end) {
    int sum = 0;
    for (int i = start; i < end; i++) {
        sum += (int)s[i];
    }
    return sum;
}

int partitionString(const char* s) {
    int n = strlen(s);
    bool narcissisticNumbers[1000] = { false };  // 存储是否是水仙花数
    generateNarcissisticNumbers(narcissisticNumbers);

    int dp[n + 1];   // 记录字符串是否可以被划分
    int ways[n + 1]; // 记录不同的划分方案数

    dp[0] = 1;       // 空字符串可以被划分
    ways[0] = 1;     // 初始只有一种划分方式

    for (int i = 1; i <= n; i++) {
        dp[i] = 0;  // 初始化为不可划分状态
        ways[i] = 0;
        for (int j = 0; j < i; j++) {
            int sum = getASCIISum(s, j, i);  // 计算从j到i的子串的ASCII和
            if (sum < 1000 && narcissisticNumbers[sum]) {  // 如果子串的ASCII和是水仙花数
                if (dp[j] == 1) {
                    dp[i] = 1;
                    ways[i] += ways[j];  // 更新到i位置的划分方式数量
                }
            }
        }
    }

    if (dp[n] == 0) {
        return 0;  // 如果无法划分,返回0
    } else if (ways[n] > 1) {
        return -1;  // 如果有多种划分方式,返回-1
    } else {
        return dp[n];  // 返回唯一划分方案的子串数量
    }
}

int main() {
    char input[1000];  // 假设输入的字符串长度不会超过1000
    printf("请输入一个字符串: ");
    fgets(input, sizeof(input), stdin);  // 从控制台读取输入的字符串

    // 去除换行符
    input[strcspn(input, "\n")] = 0;

    int result = partitionString(input);

    // 输出结果
    printf("%d\n", result);

    return 0;
}

九、C++算法源码

#include <iostream>
#include <vector>
#include <string>
#include <set>

using namespace std;

// 生成所有水仙花数
set<int> generateNarcissisticNumbers() {
    set<int> narcissisticNumbers;
    for (int i = 100; i <= 999; i++) {
        int hundred = i / 100;
        int ten = (i / 10) % 10;
        int one = i % 10;
        if (i == hundred * hundred * hundred + ten * ten * ten + one * one * one) {
            narcissisticNumbers.insert(i);
        }
    }
    return narcissisticNumbers;
}

// 计算子串的ASCII和
int getASCIISum(const string& s, int start, int end) {
    int sum = 0;
    for (int i = start; i < end; i++) {
        sum += static_cast<int>(s[i]);
    }
    return sum;
}

int partitionString(const string& s) {
    int n = s.length();
    set<int> narcissisticNumbers = generateNarcissisticNumbers(); // 获取所有水仙花数
    vector<int> dp(n + 1, 0);   // 记录字符串是否可以被划分
    vector<int> ways(n + 1, 0); // 记录不同的划分方案数

    dp[0] = 1;  // 空字符串可以被划分
    ways[0] = 1;  // 初始只有一种划分方式

    for (int i = 1; i <= n; i++) {
        dp[i] = 0;  // 初始化不可划分状态
        for (int j = 0; j < i; j++) {
            int sum = getASCIISum(s, j, i);  // 计算从j到i的子串的ASCII和
            if (narcissisticNumbers.find(sum) != narcissisticNumbers.end()) {  // 如果子串的ASCII和是水仙花数
                if (dp[j] == 1) {
                    dp[i] = 1;
                    ways[i] += ways[j];  // 更新到i位置的划分方式数量
                }
            }
        }
    }

    if (dp[n] == 0) {
        return 0;  // 如果无法划分,返回0
    } else if (ways[n] > 1) {
        return -1;  // 如果有多种划分方式,返回-1
    } else {
        return dp[n];  // 返回唯一划分方案的子串数量
    }
}

int main() {
    string input;
    cout << "请输入一个字符串: ";
    getline(cin, input);  // 从控制台读取输入的字符串

    int result = partitionString(input);

    // 输出结果
    cout << result << endl;

    return 0;
}


🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)

🏆本文收录于,华为OD机试真题(Python/JS/C/C++)

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2153761.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【亿美软通-注册/登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

探索《藏汉翻译通》小程序:跨平台的藏文翻译利器

亲爱的读者们&#xff0c;当谈及藏文与汉语之间的翻译工具时&#xff0c;您可能已经对安卓平台的《藏汉翻译通》应用和iOS平台的《藏语翻译通》应用有所耳闻。今天&#xff0c;我们想要向您推荐一款既实用又便捷的新工具——《藏汉翻译通》小程序。 这款小程序不仅能够提供精确…

中国电子学会202312青少年软件编程(Python)等级考试试卷(三级)真题

2023年12月青少年软件编程Python等级考试(三级)真题试卷 题目总数:38 总分数:100 一、选择题 第 1 题 单选题 一个非零的二进制正整数,在其末尾添加两个“0”,则该新数将是原数的?( ) A.10倍 B.2倍 C.4倍 D.8倍 第 2 题 单选题 2023年亚运会将在杭…

使用开源 Whisper 视频转文字

Whisper 是 OpenAI 开源的语音到文字的模型&#xff0c; 支持多语言&#xff0c;Whisper 模型是基于 Transformer 架构&#xff0c;音频输入、文字输出&#xff0c;具体架构如下图。 Whisper 支持多种参数&#xff0c;模型的文档中说中等尺寸的模型不支持多语言&#xff0c;我测…

LED显示屏迎来革新:GOB封装技术引领行业新风尚

在我们日常生活中&#xff0c;LED显示屏无处不在&#xff0c;从繁华的街头广告牌到家庭娱乐中心的大屏幕电视&#xff0c;它们都以鲜明的色彩和清晰的画质吸引着我们的目光。然而&#xff0c;在LED显示屏技术日新月异的今天&#xff0c;一种名为GOB&#xff08;Glue On Board&a…

asp.net门诊管理系统网站(含协同过滤算法)VS开发sqlserver数据库web结构c#编程web网页设计

一、源码特点 asp.net门诊管理系统网站是一套完善的web设计管理系统&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为vs2010&#xff0c;数据库为sqlserver2008&#xff0c;使用c#语言 开发。 应用技术&#xff1a;asp.net c…

PAT甲级-1086 Tree Traversals Again

题目 题目大意 题目给出二叉树的节点个数&#xff0c;并给出用栈遍历树的过程。要求输出树的后序遍历&#xff0c;不能有多余空格。 思路 可以看出&#xff0c;栈遍历输出的是树的中序遍历&#xff0c;而依次push进栈的是先序遍历的顺序。题目要求后序&#xff0c;即已知先序…

为什么 ECB 模式不安全

我们先来简单了解下 ECB 模式是如何工作的 ECB 模式不涉及链接模式&#xff0c;所以也就用不着初始化向量&#xff0c;那么相同的明文分组就会被加密成相同的密文分组&#xff0c;而且每个分组运算都是独立的&#xff0c;这也就意味着可以并行提高运算效率&#xff0c;但也正是…

车载软件调试工具系列---Trace32断点功能

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无利益不试图说服别人,是精神上的节…

图形化编程012(变量-倒计时)

案例展示 点击绿旗&#xff0c;使用空格键控制鳐鱼&#xff0c;按下空格向上游&#xff0c;松开下落。 在舞台右侧会出现障碍物从右向左移动&#xff0c;移动到左侧边缘发出声音并隐藏。 鳐鱼碰到障碍停止全部脚本&#xff0c;坚持60秒程序结束。 一、逻辑思维 通过读题将大…

谷歌 Chrome 最新版升级:更强的安全检查功能守护你的上网安全

谷歌 Chrome 浏览器产品经理 Andrew Kamau 在最新发布的博文中宣布&#xff0c;Chrome 浏览器迎来了新一轮的安全升级。新版 Chrome 在后台自动运行安全检查功能&#xff0c;采取了额外的主动措施来保障用户的安全。 自动撤销通知权限 新版 Chrome 浏览器采用了一项基于谷歌安…

线程知识点补充

我们之前&#xff1a; 主线程下来&#xff0c;调用了一个方法run方法&#xff0c;方法执行完后再继续往下走主线程。 咱们期望&#xff1a; 两个同时执行&#xff0c;交替执行。 一些核心概念说明&#xff1a; 一个程序写好是静态的&#xff0c;给他运行起来就是一个进程了…

Linux(7)--目录文件的创建、删除、移动、复制、重命名

文章目录 1. 创建目录、文件2. 删除目录、文件3. 移动目录、文件4. 复制目录、文件5. 重命名目录、文件 1. 创建目录、文件 使用mkdir创建目录&#xff1a; 使用touch创建文件&#xff1a; 2. 删除目录、文件 使用rm可以删除文件: 使用rm -f可以强制删除文件&#xff0c;…

Nuxt Kit 中的插件:创建与使用

title: Nuxt Kit 中的插件:创建与使用 date: 2024/9/19 updated: 2024/9/19 author: cmdragon excerpt: 摘要:本文介绍了在 Nuxt 3 框架中使用 Nuxt Kit 创建和管理插件的方法,包括使用addPlugin注册插件、创建插件文件、在Vue组件中使用插件,以及使用addPluginTemplate…

Java笔试面试题AI答之设计模式(1)

文章目录 1. 简述什么是设计模式 &#xff1f;2. 叙述常见Java设计模式分类 &#xff1f;3. Java 设计模式的六大原则 &#xff1f;4. 简述对 MVC 的理解&#xff0c; MVC 有什么优缺点&#xff1f;MVC 的三个核心部分&#xff1a;MVC 的优点&#xff1a;MVC 的缺点&#xff1a…

AIGC专栏15——CogVideoX-Fun详解 支持图文生视频 拓展CogVideoX到256~1024任意分辨率生成

AIGC专栏15——CogVideoX-Fun详解 支持图&文生视频 拓展CogVideoX到256&#xff5e;1024任意分辨率生成 学习前言项目特点生成效果相关地址汇总源码下载地址 CogVideoX-Fun详解技术储备Diffusion Transformer (DiT)Stable Diffusion 3EasyAnimate-I2V 算法细节算法组成InPa…

调节 PWM的占空比控制舵机的角度

一、PWM工作原理 让计数器从0数到自动重装载值&#xff0c;不停计数。计数值小于输出比较寄存器时输出一种电平&#xff0c;大于输出比较寄存器时使出另一种电平。 修改定时器时钟源的速度以及预分频器等设置&#xff0c;可以修改计数器计数的速度 再加上修改自动重装载值&…

Spring:统一结果私有属性造成的前端无法访问异常报错问题

用户未填写任何评价 1.问题复现 &#xff08;1&#xff09;看一段代码 controller&#xff1a; import lombok.extern.slf4j.Slf4j; import org.ljy.testdemo.common.Result; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.w…

电脑网络怎么弄动态ip :步骤详解与优势探讨

在当今的数字化时代&#xff0c;网络连接已成为我们日常生活和工作中不可或缺的一部分。对于大多数用户而言&#xff0c;动态IP地址是一种便捷且常用的网络配置方式&#xff0c;它允许设备在每次连接到网络时自动获取一个新的IP地址。这种设置不仅简化了网络管理&#xff0c;还…

毕业论文写作3步搞定!分享5款AI写毕业论文的软件

毕业论文写作是一项既重要又具挑战性的任务&#xff0c;尤其对于即将毕业的学生来说。为了帮助大家更高效地完成这一过程&#xff0c;我将分享5款AI写毕业论文的软件&#xff0c;并重点推荐千笔-AIPassPaper。 1. 千笔-AIPassPaper 千笔-AIPassPaper是一款功能强大且全面的AI…