目录

题目

思路

Code


题目

给定一个字符串和一个正整数,字符串由大小写字母和数字组成,要求从字符串中找出最大且能被给定正整数整除的数。

输入描述
1. string inputStr:第一个字符串
2. int inputDivisor:第二个正整数

输出描述
int result:返回结果值

说明
1. 给定的 inputStr 字符串长度为 1 ~ 10000,给定的 inputDivisor 的值的范围为 1 ~ 99。
2. 从 inputStr 中解析的整数不可为负,支持前导 0,数值范围为 0 ~ 999。
3. 只从字符串中提取完整的连续数字片段,每个连续数字片段只解析一次,不会再拆成更短子串。
   例如:
   - "29a0b03" -> 可提取的数字为 29、0、3
   - "0abc123" -> 可提取的数字为 0、123
   - "064" -> 解析为一个数字 64,而不是 0、6、4、64 的组合
4. 如果某个连续数字片段解析后的数值超过 999,则该数字片段无效,不参与比较。
5. 如果输入包含非法字符,则直接返回 -1。
   合法字符只包括:大小写英文字母、数字。
6. 如果找不到能被 inputDivisor 整除的数字,则返回 -1。

补充说明
1. 程序运行内存限制为 256MB;
2. 程序运行耗时不能超过 1 秒。

样例1
输入
abc123EFGED34aadD78er
2

输出
78

说明
可提取出的整数为 123、34、78。
其中 34 和 78 都能被 2 整除,返回较大的 78。

样例2
输入
nvvgr1.0verde-
3

输出
-1

说明
参数 1 字符串中包含非法字符 . 和 -。

样例3
输入
ewr23hik064ASM12VBG
4

输出
64

说明
提取出的整数为 23、64、12。
其中能被 4 整除的最大数为 64。

样例4
输入
ewr23hik064ASM12VBG
5

输出
-1

说明
提取出的整数为 23、64、12。
其中没有任何数字能被 5 整除,所以返回 -1。

思路

典型的逻辑模拟类题目。

关键口径是:只提取完整的连续数字段,不会再把一个数字段拆成更短子串;比如 064 只能解析成 64。所以做法很直接:先检查整串是否只包含字母和数字,若有非法字符直接返回 -1;然后从左到右扫描字符串,遇到一段连续数字就整段取出,转成整数。

如果这个整数在 0~999 范围内,并且能被 inputDivisor 整除,就尝试更新答案。最后输出所有合法候选中的最大值,若一个都没有则返回 -1。

Code

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String inputStr = br.readLine();
        String divisorLine = br.readLine();

        // 输入不足两行时,按失败处理。
        if (inputStr == null || divisorLine == null) {
            System.out.print(-1);
            return;
        }

        inputStr = inputStr.trim();
        int inputDivisor = Integer.parseInt(divisorLine.trim());

        // 如果字符串中存在非法字符,则直接返回 -1。
        for (int i = 0; i < inputStr.length(); i++) {
            char ch = inputStr.charAt(i);
            if (!Character.isDigit(ch) && !Character.isLetter(ch)) {
                System.out.print(-1);
                return;
            }
        }

        int best = -1;
        int n = inputStr.length();
        int i = 0;

        while (i < n) {
            // 遇到非数字字符就跳过,继续寻找下一个完整数字段。
            if (!Character.isDigit(inputStr.charAt(i))) {
                i++;
                continue;
            }

            int j = i;
            while (j < n && Character.isDigit(inputStr.charAt(j))) {
                j++;
            }

            // 只把这一整段连续数字解析成一个整数。
            int value = Integer.parseInt(inputStr.substring(i, j));

            // 只有数值在 0~999 范围内且能整除时,才参与答案比较。
            if (value <= 999 && value % inputDivisor == 0) {
                best = Math.max(best, value);
            }

            i = j;
        }

        System.out.print(best);
    }
}

Go

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
	"unicode"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	inputStr, _ := reader.ReadString('\n')
	divisorLine, _ := reader.ReadString('\n')

	inputStr = strings.TrimSpace(inputStr)
	divisorLine = strings.TrimSpace(divisorLine)

	if inputStr == "" && divisorLine == "" {
		fmt.Print(-1)
		return
	}

	inputDivisor, _ := strconv.Atoi(divisorLine)

	// 若出现非法字符,则直接返回 -1。
	for _, ch := range inputStr {
		if !unicode.IsDigit(ch) && !unicode.IsLetter(ch) {
			fmt.Print(-1)
			return
		}
	}

	best := -1
	n := len(inputStr)
	i := 0

	for i < n {
		// 非数字字符直接跳过。
		if inputStr[i] < '0' || inputStr[i] > '9' {
			i++
			continue
		}

		j := i
		for j < n && inputStr[j] >= '0' && inputStr[j] <= '9' {
			j++
		}

		// 只把完整连续数字段解析成一个整数。
		value, _ := strconv.Atoi(inputStr[i:j])

		// 数值在 0~999 范围内且能整除时,才更新答案。
		if value <= 999 && value%inputDivisor == 0 && value > best {
			best = value
		}

		i = j
	}

	fmt.Print(best)
}

C

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

int main() {
    char inputStr[20005];
    char divisorLine[100];

    if (!fgets(inputStr, sizeof(inputStr), stdin) || !fgets(divisorLine, sizeof(divisorLine), stdin)) {
        printf("-1");
        return 0;
    }

    // 去掉两行末尾换行。
    inputStr[strcspn(inputStr, "\r\n")] = '\0';
    divisorLine[strcspn(divisorLine, "\r\n")] = '\0';

    int inputDivisor = atoi(divisorLine);

    // 若存在非法字符,则直接返回 -1。
    for (int i = 0; inputStr[i] != '\0'; i++) {
        char ch = inputStr[i];
        if (!isdigit((unsigned char)ch) && !isalpha((unsigned char)ch)) {
            printf("-1");
            return 0;
        }
    }

    int best = -1;
    int n = (int)strlen(inputStr);
    int i = 0;

    while (i < n) {
        // 遇到非数字字符时跳过。
        if (!isdigit((unsigned char)inputStr[i])) {
            i++;
            continue;
        }

        int j = i;
        while (j < n && isdigit((unsigned char)inputStr[j])) {
            j++;
        }

        // 只解析完整连续数字段。
        char buffer[32];
        int len = j - i;
        strncpy(buffer, inputStr + i, len);
        buffer[len] = '\0';

        int value = atoi(buffer);

        // 只有在 0~999 范围内且能整除时,才参与最大值比较。
        if (value <= 999 && value % inputDivisor == 0) {
            if (value > best) {
                best = value;
            }
        }

        i = j;
    }

    printf("%d", best);
    return 0;
}

【华为od机试真题Python+JS+Java+Go合集】【超值优惠】:Py/JS/Java/Go合集

【华为od机试真题Python】:Python真题题库

【华为od机试真题JavaScript】:JavaScript真题题库

【华为od机试真题Java&Go】:Java&Go真题题库

【华为od机试真题C++】:C++真题题库

【华为od机试真题C语言】:C语言真题题库

【华为od面试手撕代码题库】:面试手撕代码题库

【华为od机试面试交流群】【文章底部有二维码链接,可扫码加交流群】

华为OD机试:二本院校有机会吗?
有机会,但不大,大神除外!机考分数越高越好,所以需要提前刷题。机考通过后,如果没有收到面试邀请,也不要着急,非目标院校面试邀请发的时间比较晚。非目标院校今年有点难,机试至少要考到350分,所以需要疯狂刷题,华为OD机考是有题库的,最好在考前完所有题库题目。华为OD机试:跨专业可以参加华为OD可以,但是如果你的本科院校比较差,上岸概率不大。华为OD机试:华为OD简历被锁定机试通过,性格测试也通过,但是没人联系面试,发现简历被锁定。此时需要主动去联系HR。让他帮助你查询原因。

更多推荐