2024年华为OD机试真题-查找接口成功率

华为OD机试真题-查找接口成功率-2024年OD统一考试(D卷)

题目描述:

服务之间交换的接口成功率作为服务调用关键质量特性,某个时间段内的接口失败率使用一个数组表示,数组中每个元素都是单位时间内失败率数值,数组中的数值为0~100的整数,给定一个数值(minAverageLost)表示某个时间段内平均失败率容忍值,即平均失败率小于等于minAverageLost,找出数组中最长时间段,如果未找到则直接返回NULL。

输入描述:

输入有两行内容,第一行为{minAverageLost},第二行为{数组},数组元素通过空格(" ")分隔,minAverageLost及数组中元素取值范围为0~100的整数,数组元素的个数不会超过100个。

输出描述:

找出平均值小于等于minAverageLost的最长时间段,输出数组下标对,格式{beginIndex}-{endIndx}(下标从0开始),如果同时存在多个最长时间段,则输出多个下标对且下标对之间使用空格(" ")拼接,多个下标对按下标从小到大排序。

补充说明:

示例1

输入:

1

0 1 2 3 4

输出:

0-2

说明:

A、输入解释:minAverageLost=1,数组[0, 1, 2, 3, 4]

B、前3个元素的平均值为1,因此数组第一个至第三个数组下标,即0-2

示例2

输入:

2

0 0 100 2 2 99 0 2

输出:

0-1 3-4 6-7

说明:

A、输入解释:minAverageLost=2,数组[0, 0, 100, 2, 2, 99, 0, 2]

B、通过计算小于等于2的最长时间段为:数组下标为0-1即[0, 0],数组下标为3-4即[2, 2],数组下标为6-7即[0, 2],这三个部分都满足平均值小于等2的要求,因此输出0-1 3-4 6-7

解题思路:

双指针,遍历所有的情况,检查这个区间是否可行即可,可以使用前缀和来降低复杂度,也可以不使用,这题数据很小。

c++解法:

#include<bits/stdc++.h>
#define int long long  // 使用宏定义让 int 表示 long long 类型,提高数值范围
using namespace std;
 
vector<int> line2vec()
{
    string line;  // 用于存储输入的字符串
    getline(cin, line);  // 读取一行输入
    istringstream iss(line);  // 将字符串放入字符串流中
    vector<int> res;  // 创建一个向量来存储分割后的整数
    int num;
    while (iss >> num)  // 循环读取数值,直到当前行读取完毕
        res.push_back(num);  // 将读取的数值添加到向量中
    return res;
}
 
signed main()
{
    int avg;  // 存储平均失效率容忍值
    cin >> avg;  // 读取容忍值
    getchar();  // 读取并丢弃换行符,为读取下一行数组做准备
    vector<int> a = line2vec();  // 调用 line2vec 函数读取失败率数组
 
    if (*min_element(a.begin(), a.end()) > avg)  // 检查数组中的最小元素是否大于平均失效率容忍值
    {
        cout << "NULL" << endl;  // 如果是,则输出 NULL
        return 0;  // 结束程序
    }
 
    int n = a.size();  // 获取数组元素个数
    a.insert(a.begin(), 0);  // 在数组前面插入一个0,用于简化前缀和的计算
    vector<int> pre(n+1, 0);  // 创建前缀和数组,初始值全为0
 
    for (int i = 1; i <= n; i++)  // 计算前缀和
        pre[i] = pre[i-1] + a[i];
 
    vector<pair<int, int>> ans;  // 用于存储满足条件的子数组的起止下标
    for (int len = n; len >= 1; len--)  // 从大到小尝试所有可能的子数组长度
    {
        for (int l = 1, r = len; r <= n; l++, r++)  // 在数组中滑动这个长度的窗口
        {
            int sum = pre[r] - pre[l-1];  // 计算当前窗口的和
            if (sum <= avg * len)  // 如果平均值小于等于容忍值
                ans.push_back({l, r});  // 将起止下标添加到答案中
        }
        if (ans.size())  // 如果找到了至少一个解
            break;  // 停止寻找更短的子数组
    }
 
    for (auto [l, r]: ans)  // 遍历所有找到的满足条件的子数组
        cout << l-1 << "-" << r-1 << " ";  // 输出子数组的下标,调整为从0开始的下标
    return 0;
}

Java解法:

import java.util.*;
 
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int avg = in.nextInt();  // 读取平均失败率容忍值
        in.nextLine();  // 读取并忽略掉这行后面的换行符
        String[] str = in.nextLine().split(" ");  // 读取一行字符串并按空格分割得到失败率数组
        int n = str.length;  // 数组的长度
        int minval = Integer.MAX_VALUE;  // 用来存储数组中的最小值,初始化为最大整数
        int[] a = new int[n+1];  // 创建一个新的数组a,比原数组多一个元素
        int[] pre = new int[n+1];  // 创建一个前缀和数组,同样比原数组多一个元素
        
        for (int i = 1; i <= n; i++) {
            a[i] = Integer.parseInt(str[i-1]);  // 将字符串数组转换为整数并存储
            pre[i] = pre[i-1] + a[i];  // 计算前缀和
            minval = Math.min(minval, a[i]);  // 更新数组中的最小值
        }
        
        if (minval > avg) {
            System.out.println("NULL");  // 如果数组中的最小值大于平均失效率容忍值,直接输出NULL
            return;
        }
        
        List<int[]> ans = new ArrayList<>();  // 用来存储满足条件的子数组起止位置
        for (int len = n; len >= 1; len--) {  // 从最大长度开始尝试每个可能的子数组长度
            for (int l = 1, r = len; r <= n; l++, r++) {
                int sum = pre[r] - pre[l-1];  // 计算子数组的和
                if (sum <= avg * len)  // 判断平均值是否小于等于容忍值
                    ans.add(new int[]{l, r});  // 如果满足条件,添加到结果列表
            }
            if (ans.size() > 0)
                break;  // 如果找到了符合条件的子数组,就不需要继续尝试更短的子数组
        }
        
        for (int[] p : ans)
            System.out.print((p[0]-1) + "-" + (p[1]-1) + " ");  // 输出结果,调整索引为从0开始
    }
}

Python解法:

def solve():
    avg = int(input())  # 读取输入的平均失败率容忍值
    a = list(map(int, input().split()))  # 读取接口失败率的数组
    
    if min(a) > avg:  # 检查数组中的最小值是否大于容忍值
        print("NULL")  # 如果是,则不存在任何符合条件的时间段,输出NULL
        return
    
    n = len(a)  # 计算数组长度
    a.insert(0, 0)  # 在数组前插入一个0,方便后续使用前缀和
    pre = [0] * (n+1)  # 初始化前缀和数组,大小为n+1
    
    for i in range(1, n+1):  # 计算前缀和数组
        pre[i] = pre[i-1] + a[i]
    
    ans = []  # 用来存储满足条件的时间段的下标对
    for length in range(n, 0, -1):  # 从最长的可能时间段开始检查
        for l in range(1, n - length + 2):  # 遍历所有可能的开始位置
            r = l + length - 1  # 计算结束位置
            if pre[r] - pre[l-1] <= avg * length:  # 检查这个时间段的平均失败率是否小于等于容忍值
                ans.append((l, r))  # 如果是,添加到结果列表中
        if ans:  # 一旦找到了至少一个满足条件的时间段,就不再检查更短的时间段
            break
    
    for l, r in ans:  # 遍历所有找到的时间段
        print(f"{l-1}-{r-1}", end=" ")  # 输出时间段的下标,调整为从0开始的下标,并以空格隔开
    print()  # 在所有输出完成后打印一个换行符
 
 
if __name__ == '__main__':
    solve()

欢迎交流指正~

#华为od##华为##华为od题库#
华为OD机试题库2024年 文章被收录于专栏

2024年OD统一考试(D卷),最新最完整题库。 收录130+道真题,提供解题思路,Java/Python/C++三种答案源码。

全部评论
学到了
点赞
送花
回复 分享
发布于 06-28 16:57 香港
哈哈,机考遇到了这道原题
点赞
送花
回复 分享
发布于 昨天 09:04 江苏
秋招专场
校招火热招聘中
官网直投
南京od招聘,需要的联系我哈
点赞
送花
回复 分享
发布于 昨天 18:40 江苏

相关推荐

5 6 评论
分享
牛客网
牛客企业服务