华为OD机试 - 日志限流 - 二分查找(Python/JS/C/C++ 2024 E卷 100分)

news2024/11/25 11:37:17

在这里插入图片描述

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

专栏导读

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

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

一、题目描述

某软件系统在运行过程中持续产生日志,系统每天运行N个单位时间,运行期间每单位时间产生的日志条数保存在数组records中。由于系统磁盘空间限制,每天可记录保存的日志总数上限为total条。

如果一天产生的日志条数大于total,则需要对当天每单位时间产生的日志条数进行限流后保存,要求计算每单位时间最大可保存日志数上限limit,使得每天保存的日志总量不超过total。

  • 对于单位时间内产生日志条数超过limit的日志会被记录limit条;
  • 对于单位时间内产生日志条数少于或等于limit的日志,记录全部日志。

如果一天产生的日志条数总和小于或等于total,则不需要限流,结果为-1。

任务:返回result的最大值Q或者-1。

二、输入描述

第一行为系统某一天运行的单位时间数N,1 <= N <= 10^5;
第二行为表示这一天每单位时间产生的日志条数数组records[],0 <= records[i] <= 10^5;
第三行为系统一天可以保存的日志总数total,1 <= total <= 10^9。

三、输出描述

每单位时间内最大可保存的日志条数limit,如果不需要启动限流机制,返回-1。

四、测试用例

测试用例1:

1、输入

6
3 3 8 7 10 15
40

2、输出

9

3、说明

如题目所示,limit=9 时,保存日志总数为39 ≤40,且无法找到更大的limit满足条件。

测试用例2:

1、输入

5
1 2 3 4 5
15

2、输出

-1

3、说明

总日志数为15,等于total,无需限流,返回-1。

五、解题思路

需要在日志总量超过系统保存上限 total 的情况下,找到一个每单位时间保存日志的最大上限 limit,使得每天保存的日志总量不超过 total。

具体步骤如下:

  1. 计算日志总量:首先计算数组 records 中所有日志的总和。如果总和小于或等于 total,则无需限流,直接返回 -1。
  2. 二分查找:如果总和超过 total,则需要确定一个合适的 limit。我们可以采用二分查找的方法,搜索可能的 limit 值范围从 1 到 records 数组中的最大值。对于每一个中间值 mid,计算在限流 mid 的情况下,每单位时间实际保存的日志总数。如果总数小于或等于 total,则尝试增大 mid;否则,减小 mid。最终找到的最大满足条件的 limit 即为所求。
  3. 优化计算:为了高效计算在某个 limit 下的保存日志总数,我们可以遍历数组,对每个记录取 min(records[i], mid) 的和。

采用二分查找的原因是它能在对数时间内快速缩小可能的 limit 范围,特别适用于本题中 N 和 records[i] 较大的情况。

六、Python算法源码

# Python 代码实现

import sys

def main():
    import sys
    import math

    # 读取输入
    input = sys.stdin.read().split()
    idx = 0

    # 读取单位时间数N
    N = int(input[idx])
    idx += 1

    # 读取每单位时间产生的日志数数组records
    records = []
    max_record = 0  # 记录数组中的最大值
    total_logs = 0  # 记录总日志数
    for _ in range(N):
        num = int(input[idx])
        records.append(num)
        total_logs += num
        if num > max_record:
            max_record = num
        idx += 1

    # 读取系统一天可以保存的日志总数total
    total = int(input[idx])
    idx += 1

    # 如果总日志数小于或等于total,不需要限流,输出-1
    if total_logs <= total:
        print(-1)
        return

    # 初始化二分查找的左边界和右边界
    left = 1
    right = max_record
    result = -1

    # 执行二分查找,寻找最大的limit值
    while left <= right:
        mid = left + (right - left) // 2  # 计算中间值
        saved_logs = 0  # 当前limit下保存的日志总数

        # 计算在当前limit下保存的日志总数
        for record in records:
            saved_logs += min(record, mid)
            # 如果已经超过total,提前退出循环
            if saved_logs > total:
                break

        # 判断当前limit是否可行
        if saved_logs <= total:
            result = mid  # 更新结果为当前mid
            left = mid + 1  # 尝试寻找更大的limit
        else:
            right = mid - 1  # 限流过多,减少limit

    # 输出最终结果
    print(result)

if __name__ == "__main__":
    main()

七、JavaScript算法源码

// JavaScript 代码实现

const readline = require('readline');

// 创建接口以读取输入
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

let input = [];

// 读取所有输入行
rl.on('line', (line) => {
    input = input.concat(line.trim().split(' '));
}).on('close', () => {
    let idx = 0;

    // 读取单位时间数N
    const N = parseInt(input[idx++]);

    // 读取每单位时间产生的日志数数组records
    const records = [];
    let maxRecord = 0; // 记录数组中的最大值
    let totalLogs = 0; // 记录总日志数
    for (let i = 0; i < N; i++) {
        const num = parseInt(input[idx++]);
        records.push(num);
        totalLogs += num;
        if (num > maxRecord) {
            maxRecord = num;
        }
    }

    // 读取系统一天可以保存的日志总数total
    const total = parseInt(input[idx++]);

    // 如果总日志数小于或等于total,不需要限流,输出-1
    if (totalLogs <= total) {
        console.log(-1);
        return;
    }

    // 初始化二分查找的左边界和右边界
    let left = 1;
    let right = maxRecord;
    let result = -1;

    // 执行二分查找,寻找最大的limit值
    while (left <= right) {
        const mid = Math.floor(left + (right - left) / 2); // 计算中间值
        let savedLogs = 0; // 当前limit下保存的日志总数

        // 计算在当前limit下保存的日志总数
        for (let i = 0; i < N; i++) {
            savedLogs += Math.min(records[i], mid);
            // 如果已经超过total,提前退出循环
            if (savedLogs > total) {
                break;
            }
        }

        // 判断当前limit是否可行
        if (savedLogs <= total) {
            result = mid; // 更新结果为当前mid
            left = mid + 1; // 尝试寻找更大的limit
        } else {
            right = mid - 1; // 限流过多,减少limit
        }
    }

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

八、C算法源码

/* C 代码实现 */

#include <stdio.h>

// 主函数
int main() {
    int N;
    // 读取单位时间数N
    scanf("%d", &N);

    int records[N];
    int max_record = 0; // 记录数组中的最大值
    long long total_logs = 0; // 记录总日志数

    // 读取每单位时间产生的日志数数组records
    for(int i = 0; i < N; i++) {
        scanf("%d", &records[i]);
        total_logs += records[i];
        if(records[i] > max_record) {
            max_record = records[i];
        }
    }

    long long total;
    // 读取系统一天可以保存的日志总数total
    scanf("%lld", &total);

    // 如果总日志数小于或等于total,不需要限流,输出-1
    if(total_logs <= total) {
        printf("-1\n");
        return 0;
    }

    // 初始化二分查找的左边界和右边界
    int left = 1;
    int right = max_record;
    int result = -1;

    // 执行二分查找,寻找最大的limit值
    while(left <= right) {
        int mid = left + (right - left) / 2; // 计算中间值
        long long saved_logs = 0; // 当前limit下保存的日志总数

        // 计算在当前limit下保存的日志总数
        for(int i = 0; i < N; i++) {
            if(records[i] > mid) {
                saved_logs += mid;
            }
            else {
                saved_logs += records[i];
            }
            // 如果已经超过total,提前退出循环
            if(saved_logs > total) {
                break;
            }
        }

        // 判断当前limit是否可行
        if(saved_logs <= total) {
            result = mid; // 更新结果为当前mid
            left = mid + 1; // 尝试寻找更大的limit
        }
        else {
            right = mid - 1; // 限流过多,减少limit
        }
    }

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

    return 0;
}

九、C++算法源码

// C++ 代码实现

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);

    int N;
    // 读取单位时间数N
    cin >> N;

    vector<int> records(N);
    int max_record = 0; // 记录数组中的最大值
    ll total_logs = 0; // 记录总日志数

    // 读取每单位时间产生的日志数数组records
    for(int i = 0; i < N; i++) {
        cin >> records[i];
        total_logs += records[i];
        if(records[i] > max_record){
            max_record = records[i];
        }
    }

    ll total;
    // 读取系统一天可以保存的日志总数total
    cin >> total;

    // 如果总日志数小于或等于total,不需要限流,输出-1
    if(total_logs <= total){
        cout << "-1\n";
        return 0;
    }

    // 初始化二分查找的左边界和右边界
    int left = 1;
    int right = max_record;
    int result = -1;

    // 执行二分查找,寻找最大的limit值
    while(left <= right){
        int mid = left + (right - left) / 2; // 计算中间值
        ll saved_logs = 0; // 当前limit下保存的日志总数

        // 计算在当前limit下保存的日志总数
        for(int i = 0; i < N; i++){
            saved_logs += min((ll)records[i], (ll)mid);
            // 如果已经超过total,提前退出循环
            if(saved_logs > total){
                break;
            }
        }

        // 判断当前limit是否可行
        if(saved_logs <= total){
            result = mid; // 更新结果为当前mid
            left = mid + 1; // 尝试寻找更大的limit
        }
        else{
            right = mid - 1; // 限流过多,减少limit
        }
    }

    // 输出最终结果
    cout << result << "\n";

    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/2195290.html

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

相关文章

毕业设计——springboot + VUE实现后台管理系统(集成JWT接口权限验证)

作品详情 - 高质量的代码、代码结构、和代码注释 - 漂亮的UI&#xff0c;菜单栏、标签页&#xff0c;体验、交互更好用的员工、部门、角色、菜单管理等等 - 优化基于Keepalive的标签页&#xff0c;做到标签页该缓存的时候缓存&#xff0c;比如左右切换等&#xff0c;不该缓存的…

二、图解C#教程

一、方法 {}块&#xff0c;里面的是方法体 二、Var关键字 推断出等号右边的实际类型 三、局部常量 1、声明时必须初始化 2、声明后不能改变

虚拟内存能不能完全关了?太占空间了……

前言 这几天咱们提到关于Swap区&#xff08;就是Linux上的数据交换分区&#xff09;&#xff0c;在Windows上这个功能被称为虚拟内存。 前段时间&#xff08;应该是很早之前&#xff09;&#xff0c;小白写过一篇关于虚拟内存的文章&#xff1a; Windows调大虚拟内存来代替升…

常见激活函数总结

简介&#xff1a;个人学习分享&#xff0c;如有错误&#xff0c;欢迎批评指正。 一. 激活函数的定义 激活函数&#xff08;Activation Function&#xff09;是人工神经网络中对每个神经元的输入进行非线性变换的函数。神经网络中的每个神经元都会接受来自上一层的输入&#xf…

qt_c++_xml存这种复杂类型

demo&#xff0c;迅雷链接。或者我主页上传的资源 链接&#xff1a;https://pan.xunlei.com/s/VO8bIvYFfhmcrwF-7wmcPW1SA1?pwdnrp4# 复制这段内容后打开手机迅雷App&#xff0c;查看更方便 #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow>#include…

【MySQL】使用 JDBC 连接数据库

文章目录 前言1. 认识 JDBC1.1 概念1.2 好处 2. 使用 JDBC2.1 安装数据驱动包2.2 把 jar 包导入到项目中2.3 代码编写2.4 测试结果 3. 代码优化4. 源码展示结语 前言 在 MySQL 系列中&#xff0c;我们介绍了很多内容&#xff0c;包括但不限于建库建表&#xff0c;增删查改等等…

如何使用MATLAB代码生成器生成ADRC跟踪微分器(TD) PLC源代码(SCL)

ADRC线性跟踪微分器TD详细测试 ADRC线性跟踪微分器TD详细测试(Simulink 算法框图+CODESYS ST+博途SCL完整源代码)-CSDN博客文章浏览阅读383次。ADRC线性跟踪微分器(ST+SCL语言)_adrc算法在博途编程中scl语言-CSDN博客文章浏览阅读784次。本文介绍了ADRC线性跟踪微分器的算法和…

图论day55|深度优先搜索理论基础、98. 所有可达路径(卡码网)

图论day55|深度优先搜索理论基础、98. 所有可达路径(卡码网&#xff09; 思维导图汇总深度优先搜索理论基础98.所有可达路径(卡码网)1.邻接矩阵法2.邻接表法 思维导图汇总 深度优先搜索理论基础 深度优先搜索&#xff08;dfs&#xff09;与广度优先搜索&#xff08;bfs&#xf…

@Transactional声明式事务回调编程

文章目录 1. 理论阐述2. 代码实现2.1. 问题代码2.2. 改进方案 本文参考&#xff1a; 事务回调编程 大事务问题 1. 理论阐述 最近在学习数据库事务的过程中&#xff0c;了解到了大事务的危害&#xff1a; 并发情况下&#xff0c;数据库连接资源容易耗尽锁定数据较多&#xff0…

SpringBoot企业级开发(SpringSecurity安全控制+pringBatch批处理+异步消息+系统集成SpringIntegration)

Spring Security 多个过滤器来实现所有安全的功能&#xff0c;只需要注册一个特殊的DelegatingFilterProxy过滤器到WebAppliationInitializer即可 实际使用中需要让自己的Initializer类继承AbstractSecurity WebApplicationInitializer抽象类即可。 AbstractSecurityWebAppli…

【瑞昱RTL8763E】刷屏

1 显示界面填充 用户创建的各个界面在 rtk_gui group 中。各界面中 icon[]表对界面进行描述&#xff0c;表中的每个元素代表一 个显示元素&#xff0c;可以是背景、小图标、字符等&#xff0c;UI_WidgetTypeDef 结构体含义如下&#xff1a; typedef struct _UI_WidgetTypeDef …

每年每门学科排名第一的学生 和每年总成绩都有所提升的学生

一张学生成绩表(student_scores)&#xff0c;有year-学年&#xff0c;subject-课程&#xff0c;student-学生&#xff0c;score-分数这四个字段&#xff0c;请完成如下问题&#xff1a; 问题1&#xff1a;每年每门学科排名第一的学生 问题2&#xff1a;每年总成绩都有所提升的…

【STM32 HAL库】MPU6050 DMP库移植 与 自检失败的处理

【STM32 HAL库】MPU6050 DMP库移植 与 自检失败的处理 本文参考移植步骤文件配置代码修改inv_mpu.cinv_mpu.hinv_mpu_dmp_motion_driver.c 使用 自检失败怎么处理ret -1改正DEBUG过程 ret -9改正DEBUG过程 本文参考 B站 CSDN 移植步骤 文件配置 新建一个 dmp 文件夹 并将…

【斯坦福CS144】Lab1

一、实验目的 1.实现一个流重组器——一个将字节流的小块 &#xff08;称为子串或段 &#xff09;按正确顺序组装成连续的字节流的模块&#xff1b; 2.深入理解 TCP 协议的工作方式。 二、实验内容 编写一个名为"StreamReassembler"的数据结构&#xff0c;它负责…

【Nacos入门到实战十四】Nacos配置管理:集群部署与高可用策略

个人名片 &#x1f393;作者简介&#xff1a;java领域优质创作者 &#x1f310;个人主页&#xff1a;码农阿豪 &#x1f4de;工作室&#xff1a;新空间代码工作室&#xff08;提供各种软件服务&#xff09; &#x1f48c;个人邮箱&#xff1a;[2435024119qq.com] &#x1f4f1…

原神5.1前瞻网页HTML+CSS+JS

这篇文章主要是总结一下我在制作页面的时候用到的一些技术以及经验总结&#xff0c;博主也是第一次写网页&#xff0c;代码也是在不断地“进化”&#xff0c;哪里写的不好大家可以随意指出。 下面就是一些经验总结&#xff0c;如果想看具体效果我这里也不好展示&#xff0c;需要…

pytorch导入数据集

1、概念&#xff1a; Dataset&#xff1a;一种数据结构&#xff0c;存储数据及其标签 Dataloader&#xff1a;一种工具&#xff0c;可以将Dataset里的数据分批、打乱、批量加载并进行迭代等 &#xff08;方便模型训练和验证&#xff09; Dataset就像一个大书架&#xff0c;存…

QSerialPort 串口通信示例

之前使用过MFC写过串口通信的示例&#xff0c;今年学了Qt&#xff0c;特意使用Qt写了串口通信的示例&#xff0c;发现比MFC要容易一些&#xff0c; MFC串口示例如下&#xff1a; Qt示例如下&#xff1a; Qt这个做的很简单&#xff0c;主要还是想验证一下api&#xff0c; 核心…

今日指数day8实战补充(上)

1.用户管理 1.多条件综合查询 1.1 多条件综合查询接口说明 1&#xff09;原型效果 2&#xff09;接口说明 功能描述&#xff1a;多条件综合查询用户分页信息&#xff0c;条件包含&#xff1a;分页信息 用户创建日期范围 服务路径&#xff1a;/api/users 服务方法&#xff1…

Linux的Tomcat安装部署

1.下载jdk11 java11的官方URL 此时进入可能会有登录注册,挺简单的,注册登录就好 2.上传到Linux 3.解压 命令: tar -zxvf /root/linux.jdk/jdk-11.0.24_linux-x64_bin.tar.gz 4.移动解压文件夹到新建文件夹 新建文件夹: mkdir -p /export/server 移动命令: mv jdk-11.0…