【OD机试题笔记】流浪地球

题目描述

流浪地球计划在赤道上均匀部署了N个转向发动机,按位置顺序编号为0~N-1。

初始状态下所有的发动机都是未启动状态;
发动机启动的方式分为”手动启动"和”关联启动"两种方式;
如果在时刻1一个发动机被启动,下一个时刻2与之相邻的两个发动机就会被”关联启动”;
如果准备启动某个发动机时,它已经被启动了,则什么都不用做;
发动机0与发动机N-1是相邻的;
地球联合政府准备挑选某些发动机在某些时刻进行“手动启动”。当然最终所有的发动机都会被启动。

哪些发动机最晚被启动呢?

输入描述
第一行两个数字N和E,中间有空格
N代表部署发动机的总个数,E代表计划手动启动的发动机总个数
1<N<=1000,1<=E<=1000,E<=N
接下来共E行,每行都是两个数字T和P,中间有空格
T代表发动机的手动启动时刻,P代表此发动机的位置编号。
0<=T<=N.0<=P<N
输出描述
第一行一个数字N,以回车结束
N代表最后被启动的发动机个数
第二行N个数字,中间有空格,以回车结束
每个数字代表发动机的位置编号,从小到大排序

** 示例1
输入
8 2
0 2
0 6

输出
2
0 4

说明>
8个发动机,时刻0启动2和6号发动机

** 示例2
输入:
8 2
0 0
1 7

输出:
1
4

说明>
8个发动机,时刻0手动启动0,时刻1手动启动7.

思路

以时间为轴,模拟扩散过程,追踪每个节点的最早启动时间,本质是环形数组上的广度优先搜索(BFS)。

代码

function solution() {
    const [N, E] = readline().split(' ').map(Number);
    const manualStarts = [];
    for (let i = 0; i < E; i++) {
        const [T, P] = readline().split(' ').map(Number);
        manualStarts.push({ t: T, p: P });
    }

    // 初始化所有发动机的启动时间为无穷大
    const startTime = new Array(N).fill(Infinity);
    const queue = [];

    // 处理手动启动,记录最早启动时间并加入队列
    for (const { t, p } of manualStarts) {
        if (startTime[p] > t) {
            startTime[p] = t;
            queue.push({ t, p });
        }
    }

    // 按启动时间排序初始队列,确保先处理早启动的
    queue.sort((a, b) => a.t - b.t);

    // 用指针处理队列(避免shift操作的性能问题)
    let ptr = 0;
    while (ptr < queue.length) {
        const { t, p } = queue[ptr];
        ptr++;

        // 计算左右邻居(环形数组处理)
        const left = (p - 1 + N) % N;
        const right = (p + 1) % N;

        // 关联启动左邻居
        if (startTime[left] > t + 1) {
            startTime[left] = t + 1;
            queue.push({ t: t + 1, p: left });
        }

        // 关联启动右邻居
        if (startTime[right] > t + 1) {
            startTime[right] = t + 1;
            queue.push({ t: t + 1, p: right });
        }
    }

    // 找到最晚启动时间
    const maxTime = Math.max(...startTime);

    // 收集所有最晚启动的发动机
    const result = [];
    for (let i = 0; i < N; i++) {
        if (startTime[i] === maxTime) {
            result.push(i);
        }
    }

    // 排序并输出
    result.sort((a, b) => a - b);
    console.log(result.length);
    console.log(result.join(' '));
}


// 测试用例
const cases = [
    `8 2
    0 2
    0 6`,
    `8 2
    0 0
    1 7`
];

let caseIndex = 0, lineIndex = 0;
const readline = (() => {
    let lines = [];
    return () => {
        if (!lineIndex) lines = cases[caseIndex].trim().split('\n').map(l => l.trim());
        return lines[lineIndex++];
    };
})();

cases.forEach((_, i) => {
    caseIndex = i;
    lineIndex = 0;
    solution();
    console.log('-------');
});

### 华为OD考中的《流浪地球》题目分析 华为OD考确实包含了与电影《流浪地球》相关的编程挑战题[^1]。这类题目通常涉及复杂的算法设计和数据结构应用,旨在考察考生的逻辑思维能力和编程技巧。 #### 题目概述 该类题目可能围绕《流浪地球》的情节设定展开,比如行星推进器的能量计算、避难所资源分配等问题。具体来说: - **能量计算**:给定一系列参数(如发动功率、运行时间),编写程序来计算所需的总能量消耗。 ```python def calculate_energy(power, time): """ 计算所需能量 参数: power (float): 发动功率 time (int): 运行时间(秒) 返回: float: 总能量需求 """ total_energy = power * time return round(total_energy, 2) ``` - **资源分配优化**:假设存在多个地下城,每个城市有不同的物资需求量,在有限的供应条件下如何合理分配这些物资以满足尽可能多的城市生存条件。 ```python from typing import List def allocate_resources(cities_needs: List[int], available_supply: int) -> List[int]: """ 资源最优分配方案 参数: cities_needs (List[int]): 各个城市的需求列表 available_supply (int): 可用供给总量 返回: List[int]: 分配后的剩余需求列表 """ sorted_cities = sorted((need, i) for i, need in enumerate(cities_needs)) allocated = [0]*len(cities_needs) remaining_supply = available_supply for need, idx in sorted_cities: if remaining_supply >= need: allocated[idx] = need remaining_supply -= need return [(cities_needs[i]-allocated[i]) for i in range(len(cities_needs))] ``` 上述例子展示了两种不同类型的潜在问题及其解决方案框架。实际考试中可能会有更多细节上的变化或者更复杂的要求[^2]。 #### 解决策略建议 对于准备此类特定主题的试题,除了熟悉基本的数据处理外,还应该加强对科幻背景故事的理解,以便更好地融入到解题思路当中去。同时也要注重练习常见的算法模式,提高解决未知问题的能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值