华为OD机试真题---手机App防沉迷系统

题目概述

智能手机在方便我们生活的同时,也侵占了大量时间。手机App防沉迷系统旨在帮助用户合理规划手机App使用时间,确保在正确的时间做正确的事。系统的主要功能包括:

  • 在一天24小时内,可注册每个App的允许使用时段。
  • 一个时段只能使用一个App,即不能同时注册多个App在同一时间段内使用。
  • App有优先级,数值越高,优先级越高。注册时,如果高优先级的App时间和低优先级的时段有冲突,系统会自动注销低优先级的时段;如果App的优先级相同,则后添加的App不能注册。

编程实现

编程实现时,需要处理输入数据,包括App的数量、每个App的注册信息(名称、优先级、起始时间、结束时间),并根据输入的时间点返回该时间点可用的App名称。如果时间点没有注册任何App,则返回“NA”。


运行示例解析

以下是一个具体的运行示例及其解析:

输入示例
2
App1 1 09:00 10:00
App2 2 09:10 09:30
09:20
解析过程
  1. 读取输入

    • 第一行表示要注册的App数量,这里是2。
    • 接下来两行是App的注册信息:
      • App1,优先级1,注册时段09:00-10:00。
      • App2,优先级2,注册时段09:10-09:30。
    • 最后一行是查询时间点,这里是09:20。
  2. 处理注册信息

    • 根据注册信息,将App及其相关信息存储起来,并检查时间冲突和优先级。
    • 在这个例子中,App1和App2的注册时段有冲突(09:10-09:30重叠)。由于App2的优先级(2)高于App1(1),系统会注销App1在该时间段的注册,只保留App2的注册信息。
  3. 查询时间点

    • 查询时间为09:20,根据已注册的App信息,此时可用的App是App2。
输出结果
App2

编程注意事项

  • 输入数据的格式和范围需要严格检查,确保符合题目要求。
  • 时间处理时,需要注意起始时间和结束时间的比较,以及注册信息中的时间段是否包含起始时间点但不包含结束时间点。
  • 优先级处理时,需要确保高优先级的App能够覆盖低优先级的App的注册信息。
  • 如果存在多个App在同一时间点冲突且优先级相同的情况,需要按照题目要求处理(如后添加的App不能注册)。

代码实现

import java.util.*;

public class AppScheduler {

    private final Map<String, Integer> appPriorityMap;
    private final Map<Integer, String> timeSlotMap;

    public AppScheduler() {
        appPriorityMap = new HashMap<>();
        timeSlotMap = new TreeMap<>();
    }

    /**
     * 注册应用程序的优先级和运行时间
     * 
     * @param appName 应用程序的名称
     * @param priority 应用程序的优先级,数值越小优先级越高
     * @param startTime 应用程序开始运行的时间(格式为"HH:mm")
     * @param endTime 应用程序结束运行的时间(格式为"HH:mm")
     */
    public void registerApp(String appName, int priority, String startTime, String endTime) {
        // 将开始时间和结束时间转换为小时数
        int startHour = parseTime(startTime);
        int endHour = parseTime(endTime);
    
        // 如果应用程序还不在优先级映射中,直接添加
        if (!appPriorityMap.containsKey(appName)) {
            appPriorityMap.put(appName, priority);
        } else {
            // 如果应用程序已经在优先级映射中,只有当新优先级更高时才更新
            int currentPriority = appPriorityMap.get(appName);
            if (priority < currentPriority) {
                return;
            }
            appPriorityMap.put(appName, priority);
        }
    
        // 遍历应用程序的运行时间,尝试在时间槽映射中注册
        for (int i = startHour; i < endHour; i++) {
            // 如果时间槽已经被占用,只有当新优先级更高时才替换
            if (timeSlotMap.containsKey(i)) {
                String existingAppName = timeSlotMap.get(i);
                int existingPriority = appPriorityMap.get(existingAppName);
                if (priority > existingPriority) {
                    timeSlotMap.put(i, appName);
                }
            } else {
                // 如果时间槽未被占用,直接注册
                timeSlotMap.put(i, appName);
            }
        }
    }

    /**
     * 根据查询时间获取应用程序名称
     * 此方法用于根据给定的查询时间确定并返回对应的应用程序名称如果在给定的时间段内找不到确切的应用程序,则返回"NA"
     * 
     * @param queryTime 查询时间,将被解析以确定对应的时间段
     * @return 在指定时间段内运行的应用程序的名称,如果找不到则返回"NA"
     */
    public String getAppAtTime(String queryTime) {
        // 解析查询时间,返回对应的小时数
        int queryHour = parseTime(queryTime);
        // 根据查询时间对应的小时数,在时间槽映射中查找对应的应用程序名称,如果找不到,则默认返回"NA"
        return timeSlotMap.getOrDefault(queryHour, "NA");
    }

    /**
     * 解析时间字符串为分钟数
     * 
     * @param time 时间字符串,格式为"hh:mm",其中hh为小时数,mm为分钟数
     * @return 从午夜开始到指定时间的总分钟数
     */
    private int parseTime(String time) {
        // 将时间字符串按":"分割,得到小时和分钟部分
        String[] parts = time.split(":");
        // 计算总分钟数,小时数乘以60加上分钟数
        return Integer.parseInt(parts[0]) * 60 + Integer.parseInt(parts[1]);
    }

    /**
     * 主函数,用于处理应用程序调度器的输入和输出
     * @param args 命令行参数
     */
    public static void main(String[] args) {
        // 创建Scanner对象,读取系统输入
        Scanner scanner = new Scanner(System.in);
        
        // 读取并存储输入的程序数量
        int numApps = scanner.nextInt();
        // 消费掉输入中的换行符,准备读取下一行数据
        scanner.nextLine();

        // 创建应用程序调度器实例
        AppScheduler scheduler = new AppScheduler();

        // 循环读取每个应用程序的注册信息,并注册到调度器中
        for (int i = 0; i < numApps; i++) {
            // 读取应用程序名称、优先级、开始时间和结束时间
            String appName = scanner.next();
            int priority = scanner.nextInt();
            String startTime = scanner.next();
            String endTime = scanner.next();
            
            // 在调度器中注册应用程序
            scheduler.registerApp(appName, priority, startTime, endTime);
        }

        // 读取查询的时间点
        String queryTime = scanner.next();
        // 输出在查询时间点正在运行的应用程序信息
        System.out.println(scheduler.getAppAtTime(queryTime));
    }

}


解析步骤

1、定义数据结构:

  • appPriorityMap:存储 App 名称和优先级。
  • timeSlotMap:存储时间段和对应的 App 名称。

2、处理输入数据:

  • 读取输入并解析。

3、注册 App:

  • 根据优先级和时间冲突处理注册信息。

4、查询 App:

  • 根据时间点查询可用的 App 名称。
示例运行
输入示例
2  
App1 1 09:00 10:00  
App2 2 09:10 09:30  
09:20
输出结果
App2
华为OD机试真题-学生重新排队是一个典的编程问题,下面是问题和解决路: 问题描述: 有n个学生站成一排,每个学生都有一个独一无二身份ID。现在给定一个初始的学生排列顺序,以及一系列的交换操作,交换操作表示将两个学生的位置进行交换。请你编写一个算法,输出最终的学生排列顺序。 解决思路: 这个问题可以使用数组来表示学生的排列顺序。首先,我们需要根据初始的学生排列顺序构建一个映射表,将每个学生的ID与其在数组中的位置对应起来。然后,我们按照给定的交换操作,更新映射表中学生的位置信息。最后,根据更新后的映射表,构建最终的学生排列顺序。 具体步骤如下: 1. 构建映射表:遍历初始的学生排列顺序,将每个学生的ID与其在数组中的位置对应起来,可以使用哈希表来实现。 2. 执行交换操作:按照给定的交换操作,更新映射表中学生的位置信息。 3. 构建最终的学生排列顺序:根据更新后的映射表,构建最终的学生排列顺序。 下面是一个示例代码,用于解决这个问题: ```python def rearrange_students(initial_order, swap_operations): # 构建映射表 mapping = {} for i, student_id in enumerate(initial_order): mapping[student_id] = i # 执行交换操作 for swap in swap_operations: student1, student2 = swap mapping[student1], mapping[student2] = mapping[student2], mapping[student1] # 构建最终的学生排列顺序 final_order = [0] * len(initial_order) for student_id, position in mapping.items(): final_order[position] = student_id return final_order ``` 使用上述代码,你可以通过传入初始的学生排列顺序和交换操作,得到最终的学生排列顺序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值