华为OD机考2025C卷 - 快速人名查找 (Java & Python& JS & C++ & C )

最新华为上机考试

真题目录:点击查看目录
华为OD面试真题精选:点击立即查看
2025华为od机试2025C卷-华为OD上机考试2025年C卷

题目描述

给一个字符串,表示用’,’分开的人名。

然后给定一个字符串,进行快速人名查找,符合要求的输出。

快速人名查找要求︰人名的每个单词的连续前几位能组成给定字符串,一定要用到每个单词。

输入描述

第一行是人名,用’,’分开的人名
第二行是 查找字符串

输出描述

输出满足要求的人名

用例1

输入

zhang san,zhang san san
zs

输出

zhang san

用例2

输入

zhang san san,zhang an sa,zhang hang,zhang seng,zhang sen a
zhas

输出

zhang an sa,zhang seng

C++

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

bool dfs(vector<string>& person, int pi, string exp, int ej) {
    if (pi == person.size() || ej == exp.length()) {
        return (pi == person.size() && ej == exp.length());
    }
    string name = person[pi];
    if (name[0] != exp[ej]) {
        return false;
    }
    int cnt = 1;
    while (cnt < name.length() && ej + cnt < exp.length() && name[cnt] == exp[ej + cnt]) {
        if (dfs(person, pi + 1, exp, ej + cnt + 1)) {
            return true;
        }
        cnt++;
    }
    return dfs(person, pi + 1, exp, ej + 1);
}

int main() {
    vector<string> names;
    string input;
    getline(cin, input);
    string name;
    for (int i = 0; i < input.size(); i++) {
        if (input[i] == ',') {
            names.push_back(name);
            name = "";
        } else {
            name += input[i];
        }
    }
    names.push_back(name);
    string exp;
    cin >> exp;
    string ans = "";
    for (string name : names) {
        vector<string> person;
        string word;
        for (int i = 0; i < name.length(); i++) {
            if (name[i] == ' ') {
                person.push_back(word);
                word = "";
            } else {
                word += name[i];
            }
        }
        person.push_back(word);
        if (dfs(person, 0, exp, 0)) {
            ans = ans.empty() ? name : ans + "," + name;
        }
    }
    cout << ans << endl;
    return 0;
}

JavaScript

const readline = require("readline");
// 创建readline接口实例
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});
// 定义一个空数组,用于存储输入的数据
const input = [];
// 监听控制台的输入
rl.on("line", (line) => {
  // 将每一行的数据存入数组
  input.push(line);
  // 当输入的数据达到2行时,开始处理数据
  if (input.length === 2) {
    const names = input[0].split(","); // 将人名以逗号分隔并存储在数组中
    const abbr = input[1]; // 存储查找字符串
      const result = []; // 存储符合要求的人名
  for (let name of names) { // 遍历人名数组
    const parts = name.split(" "); // 将人名以空格分隔并存储在数组中
    if (parts.length > abbr.length) continue; // 如果人名的单词数大于查找字符串的长度,则跳过当前人名
    const res = dfs(parts, 0, abbr, 0); // 调用dfs函数查找是否符合要求
    if (res) { // 如果符合要求,则将该人名存储到结果数组中
      result.push(name);
    }
  }
    console.log(result.join(",")); // 输出满足要求的人名
    // 处理完数据后,清空input数组
    input.length = 0;
  }
});


// 定义dfs函数,用于深度优先搜索查找符合要求的人名
function dfs(parts, index, abbr, start) {
  if (start >= abbr.length) return index >= parts.length; // 如果查找字符串已经被匹配完,则判断人名的单词数是否被匹配完
  for (let i = index; i < parts.length; i++) { // 遍历人名的单词数组
    const part = parts[i]; // 取出当前单词
    for (let j = 0; j < part.length; j++) { // 遍历单词的每一个字符
      if (start < abbr.length && part[j] == abbr[start]) { // 如果当前字符与查找字符串的当前字符相等,则继续匹配下一个字符
        const res = dfs(parts, i + 1, abbr, ++start); // 递归调用dfs函数,继续匹配下一个单词
        if (res) return true; // 如果匹配成功,则返回true
      } else {
        return false; // 如果匹配失败,则返回false
      }
    }
  }
  return false; // 如果所有单词都被匹配完,但是查找字符串还没有被匹配完,则返回false
}

Java

import java.util.*;

public class Main {


    // 一定要用到每个单词
    // 前i个字符去匹配exp的前j个字符
    public static boolean dfs(List<String> person, int pi, String exp, int ej) {
        // 有任意一方已经使用完了
        if (pi == person.size() || ej == exp.length()) {
            return (pi == person.size() && ej == exp.length()); // 只有两方同时使用完了,才是ok的
        }

        // 开始匹配,对于当前person[pi]
        // 其首字母一定要匹配,否则这个字符就不能用
        // 对于当前person[i],它可以取用person[0...]去匹配exp[ej]
        String name = person.get(pi);

        // 首字母不匹配,直接退出
        if (name.charAt(0) != exp.charAt(ej)) {
            return false;
        }

        // name和exp开始匹配
        // name消耗多个exp
        int cnt = 1;
        while (cnt < name.length() && ej + cnt < exp.length() && name.charAt(cnt) == exp.charAt(ej + cnt)) {
            if (dfs(person, pi + 1, exp, ej + cnt + 1)) {
                return true;
            }
            cnt++;
        }

        // 首字母匹配,那么直接进行下一个匹配
        return dfs(person, pi + 1, exp, ej + 1);
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        List<String> names = Arrays.asList(scanner.nextLine().split(","));
        String exp = scanner.next();
        String ans = "";
        for (String name : names) {
            List<String> person = Arrays.asList(name.split(" "));
            if (dfs(person, 0, exp, 0)) {
                ans = ans.isEmpty() ? name : ans + "," + name;
            }
        }
        System.out.println(ans);
    }
}

Python

from typing import List

def dfs(person: List[str], pi: int, exp: str, ej: int) -> bool:
    if pi == len(person) or ej == len(exp):
        return pi == len(person) and ej == len(exp)
    
    name = person[pi]
    
    if name[0] != exp[ej]:
        return False
    
    cnt = 1
    while cnt < len(name) and ej + cnt < len(exp) and name[cnt] == exp[ej + cnt]:
        if dfs(person, pi + 1, exp, ej + cnt + 1):
            return True
        cnt += 1
    
    return dfs(person, pi + 1, exp, ej + 1)


names = input().split(',')
exp = input()
ans = ""
for name in names:
    person = name.split(' ')
    if dfs(person, 0, exp, 0):
        ans = name if ans == "" else ans + "," + name
print(ans)

fengmian

完整用例

用例1

zhang san,zhang san san
zs

用例2

zhang san san,zhang an sa,zhang hang,zhang seng,zhang sen a
zhas

用例3

zhang san,zhao si,li wu
zhangsan

用例4

li si,wang wu,zhao liu
ww

用例5

zhang san san,zhang an sa,zhang hang,zhang seng,zhang sen a
zhas

用例6

liu qi,liu liu qi,liu qi qi,liu qi qi qi
lqq

用例7

wang wu,wang wang wu,wang wu wu,wang wu wu wu
www

用例8

chen shi,chen chen shi,chen shi shi,chen shi shi shi
css

用例9

wang wu,wang wang wu,wang wu wu,wang wu wu wu,wang wu wu wu wu
wwww

用例10

chen shi,chen chen shi,chen shi shi,chen shi shi shi,chen shi shi shi shi
cssss
### 华为OD机考 2025C - 分月饼 算法题解 在华为OD机考中,分月饼问题通常可以转化为经典的&ldquo;整数拆分&rdquo;或&ldquo;分配问题&rdquo;,即在给定的约束条件下,将 $ n $ 个月饼分给 $ m $ 个员工,每个员工至少分到 1 个月饼,求所有可能的分配方案数量或满足特定条件的最优解。 该问题可以通过**动态规划**或**递归+剪枝**的方式解决。以下是一个基于动态规划的解法,用于计算所有可能的分配方式数量。 ```python def distribute_mooncakes(n, m): # dp[i][j] 表示将 j 个月饼分给前 i 个员工的方案数 dp = [[0] * (n + 1) for _ in range(m + 1)] # 初始化:分 0 个月饼给 0 个员工,有 1 种方式 dp[0][0] = 1 for i in range(1, m + 1): for j in range(i, n + 1): # 每个员工至少分到 1 个月饼,所以当前员工可以分到 k 个月饼(k &gt;= 1) for k in range(1, j - i + 2): dp[i][j] += dp[i - 1][j - k] return dp[m][n] ``` 上述代码中,`dp[i][j]` 表示将 `j` 个月饼分给前 `i` 个员工的方案数。通过逐步构建状态转移方程,可以高效地计算出所有合法的分配方式数量。此方法适用于数据规模不大的情况,在中通常能够通过测用例[^1]。 如果题目要求输出所有具体的分配方案,则可以采用**回溯法**进行枚举: ```python def find_all_distributions(n, m): result = [] def backtrack(index, remain, path): if index == m - 1: path.append(remain) result.append(path[:]) path.pop() return for i in range(1, remain - (m - index - 1) + 1): path.append(i) backtrack(index + 1, remain - i, path) path.pop() backtrack(0, n, []) return result ``` 该函数通过递归地为每个员工分配月饼,并在最后一个员工时将剩余全部分配,从而枚举出所有合法的分配方案。 ### 优化思路 - 如果题目要求的是&ldquo;最大最小差异&rdquo;或&ldquo;最公平分配&rdquo;,则可以采用**二分查找 + 贪心**的方式,结合可行性判断来优化搜索过程。 - 若数据规模较大,可使用**记忆化搜索**或**滚动数组**优化空间复杂度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

算法大师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值