华为OD机试:打印任务排序

标题:最大矩阵和 | 时间限制:1 秒 | 内存限制:262144K | 语言限制:不限

某个打印机根据打印队列执行打印任务。打印任务分为九个优先级,分别用数字 1~9 表示, 数字越大优先级越高。打印机每次从队列头部取出第一个任务 A,然后检查队列余下任务中 有没有比 A 优先级更高的任务,如果有比 A 优先级高的任务,则将任务 A 放到队列尾部, 否则就执行任务 A 的打印。请编写一个程序,根据输入的打印队列,输出实际的打印顺序

输入描述:

输入一行,为每个任务的优先级,优先级之间用逗号隔开,优先级取值范围是 1~9

输出描述:

输出一行,为每个任务的打印顺序,打印顺序从 0 开始,用逗号隔开

示例 1

输入 9,3,5

输出 0,2,1

说明

队列头部任务的优先级为 9,最先打印,故序号为 0;接着队列头部任务优先级为 3,队列 中还有优先级为 5 的任务,优先级 3 任务被移到队列尾部;接着打印优先级为 5 的任务,故 其序号为 1;最后优先级为 3 的任务的序号为 2

示例 2

输入 1,2,2

输出 2,0,1

说明

队列头部任务的优先级为 1,被移到队列尾部;接着顺序打印两个优先级为 2 的任务,故其序号分别为 0 和 1;最后打印剩下的优先级为 1 的任务,其序号为 2

解题思路:创建一个Task对象来存储数据,包括优先级(输入优先级)、index(优先级下标)和order(打印顺序),把Task赋值存储到list中,处理排序后,再将order赋值,输出即可。详见代码注释。

import java.util.ArrayList;
import java.util.List;

public class Test12 {

    public static void main(String[] args) {
        String str = "9,8,1,2,8,2,3";
        String[] arr = str.split(",");
        List<Task> listOrigin = new ArrayList<>();//保存原始数据
        List<Task> list = new ArrayList<>();//处理数据
        for (int i = 0; i < arr.length; i++) {
            listOrigin.add(new Task(Integer.parseInt(arr[i]), i));
            list.add(new Task(Integer.parseInt(arr[i]), i));
        }
        //排队处理list,如果找到优先级更大的值,就把当前值remove,然后放在list的末尾
        for (int i = 0; i < list.size() - 1; i++) {
            Task task1 = list.get(i);
            for (int j = i + 1; j < list.size(); j++) {
                Task task2 = list.get(j);
                if (task2.priority > task1.priority) {
                    list.remove(i);
                    list.add(task1);
                    i--;
                    break;
                }
            }
        }
        //将原始数据的order赋值
        for (int i = 0; i < listOrigin.size(); i++) {
            Task t = listOrigin.get(i);
            for (int j = 0; j < list.size(); j++) {
                if (t.index == list.get(j).index) {
                    t.order = j;
                    break;
                }
            }
        }
        //打印数据
        for (int i = 0; i < listOrigin.size(); i++) {
            System.out.print(listOrigin.get(i).order + " ");
        }
    }

    static class Task {
        private int priority;
        private int index;
        private int order;

        public Task(int priority, int index) {
            this.priority = priority;
            this.index = index;
        }
    }
}

### 华为 OD 指示灯 排序 算法 实现 #### 问题分析 华为 OD 中的指示灯排序问题是典型的多条件排序问题,主要考察候选人的数据处理能力和算法设计能力。该问题的核心在于如何通过 AI 提供的坐标信息对多个指示灯进行合理的排序[^1]。 具体来说,问题要求按照以下规则实现排序: 1. **基准灯的选择**:从未排序的灯中选取最靠上的灯作为基准灯。 2. **同行判断**:如果两盏灯的高度差小于等于灯半径,则认为它们处于同一行。 3. **同行内的排序**:对于与基准灯位于同一行的所有灯,按照其 `x1` 坐标从小到大排列。 4. **重复操作**:直到所有灯都被排序完成为止。 以下是具体的解决方案及其代码实现: --- #### 解决方案 ##### 数据结构定义 为了便于管理每个灯的信息,可以定义一个类来封装灯的属性(编号、坐标范围等),并通过方法简化同行判断和比较逻辑。 ```python class Light: def __init__(self, no, x1, y1, x2, y2): self.no = no # 灯的编号 self.x1 = x1 # 左上角横坐标 self.y1 = y1 # 左上角纵坐标 self.x2 = x2 # 右下角横坐标 self.y2 = y2 # 右下角纵坐标 @property def height(self): # 计算灯的高度 return abs(self.y2 - self.y1) @property def radius(self): # 计算灯的半径 return self.height / 2 def is_in_same_row(self, other_light): # 判断是否在同一行 return abs(self.y1 - other_light.y1) <= self.radius and \ abs(self.y1 - other_light.y1) <= other_light.radius ``` --- ##### 主要逻辑流程 根据题目描述,整个排序过程可以通过以下几个步骤实现: 1. 初始化灯列表并验证输入的有效性。 2. 使用布尔数组记录哪些灯已经被选入最终结果。 3. 循环遍历未被选择的灯,从中选出当前最高(即最小 `y1`)的灯作为基准灯。 4. 找出与基准灯同属一行的所有灯,并将其按 `x1` 进行升序排序。 5. 将这些灯依次加入结果列表,并标记为已选择。 6. 当所有灯均被选择后结束循环,输出结果。 下面是完整的 Python 实现代码: ```python def sort_lights(n, lights_info): # 创建灯对象列表 lights = [] for info in lights_info: no, x1, y1, x2, y2 = map(int, info.split()) lights.append(Light(no, x1, y1, x2, y2)) # 初始化辅助变量 selected = [False] * n result = [] while True: # 寻找尚未选择的最高灯 min_y_index = None min_y_value = float('inf') for i in range(len(lights)): if not selected[i] and lights[i].y1 < min_y_value: min_y_index = i min_y_value = lights[i].y1 if min_y_index is None: # 如果没有剩余未选择的灯则退出 break base_light = lights[min_y_index] same_row_lights = [] # 存储与基准灯同行的灯 for j in range(len(lights)): if not selected[j] and base_light.is_in_same_row(lights[j]): same_row_lights.append((lights[j], lights[j].x1)) # 对同行灯按 x1 排序 same_row_lights.sort(key=lambda x: x[1]) for light_tuple in same_row_lights: result.append(light_tuple[0].no) selected[lights.index(light_tuple[0])] = True return result # 输入样例测 if __name__ == "__main__": input_data = [ "1 1 2 3 4", "2 5 7 8 9", "3 2 1 4 3", "4 6 6 9 8", "5 3 5 5 7" ] output = sort_lights(5, input_data) print(output) # 输出排序后的灯编号序列 ``` --- #### 复杂度分析 - 时间复杂度:假设总共有 \(N\) 盏灯,在每次迭代中都需要扫描一次灯列表以寻找基准灯,同时还需要筛选出行内灯并对其进行排序。因此时间复杂度大致为 \(O(N^2)\),其中排序部分的时间开销较小。 - 空间复杂度:额外的空间主要用于存储灯的对象实例以及一些临时变量,整体空间需求为 \(O(N)\)[^2]。 --- #### 注意事项 1. 输入校验非常重要,需确保满足约束条件(如灯的数量范围、坐标合法性等)。 2. 同行判定依赖于灯的几何特性(高度/半径),应严格遵循给定公式计算偏差阈值[^3]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值