华为OD机试 2025B卷 - 区间交集 (2025B卷 200分)

区间交集

华为OD机试真题目录: 点击去查看

2025B卷 200分题型

题目描述

给定一组闭区间,其中部分区间存在交集。

任意两个给定区间的交集,称为公共区间(如:[1,2],[2,3]的公共区间为[2,2],[3,5],[3,6]的公共区间为[3,5])。

公共区间之间若存在交集,则需要合并(如:[1,3],[3,5]区间存在交集[3,3],需合并为[1,5])。

按升序排列输出合并后的区间列表。

输入描述

一组区间列表,

区间数为 N: 0<=N<=1000;

区间元素为 X: -10000<=X<=10000。

备注

  • 区间元素均为数字,不考虑字母、符号等异常输入。
  • 单个区间认定为无公共区间。

输出描述

升序排列的合并区间列表

用例1

### 华为OD路灯问题编程解法 #### 问题析 该问题是典型的区间覆盖问题,目标是计算在一段连续区域内未被覆盖的部长度。具体来说,给定一系列路灯的位置及其对应的照明半径,需找出这些路灯未能完全照亮的区域总长度[^1]。 为了高效解决问题,可以采用如下方法: 1. **提取有效范围**:对于每一个路灯,基于其位置和照明半径,确定它能够照亮的具体区间。 2. **合并重叠区间**:通过排序并处理可能存在的区间交集,最终得到一组不相交的有效光照区间。 3. **计算空白部**:利用已知的第一盏灯到最后一盏灯的整体距离减去实际被照亮的距离,得出剩余未被覆盖的长度。 以下是具体的算法设计以及不同语言下的代码实现示例。 --- #### Python 实现 ```python def unlit_length(road_lights, total_distance): intervals = [] # 计算每个路灯的实际照射区间 for light in road_lights: start = max(light['position'] - light['radius'], 0) end = min(light['position'] + light['radius'], total_distance) intervals.append((start, end)) # 对区间按照起点进行排序 intervals.sort(key=lambda x: x[0]) merged_intervals = [] prev_start, prev_end = None, None # 合并不相交或者相邻的区间 for interval in intervals: current_start, current_end = interval if not merged_intervals or merged_intervals[-1][1] < current_start: merged_intervals.append(interval) prev_start, prev_end = current_start, current_end else: merged_intervals[-1] = (merged_intervals[-1][0], max(current_end, merged_intervals[-1][1])) covered_length = sum(end - start for start, end in merged_intervals) return total_distance - covered_length # 测数据 lights_data = [ {'position': 0, 'radius': 50}, {'position': 100, 'radius': 60} ] total_road_length = 200 result = unlit_length(lights_data, total_road_length) print(f"Uncovered length is {result} meters.") ``` 上述程序定义了一个函数 `unlit_length` 来接收路灯列表与道路全长作为输入参数,并返回未被灯光覆盖路段的累计长度[^2]。 --- #### C++ 实现 ```cpp #include <iostream> #include <vector> #include <algorithm> using namespace std; struct Light { int position; int radius; }; int calculateUnlitLength(vector<Light> lights, int totalDistance) { vector<pair<int, int>> intervals; for(auto &light : lights){ int start = max(light.position - light.radius, 0); int end = min(light.position + light.radius, totalDistance); intervals.emplace_back(start, end); } sort(intervals.begin(), intervals.end()); vector<pair<int,int>> mergedIntervals; for(auto &[s,e] : intervals){ if(!mergedIntervals.empty() && s <= mergedIntervals.back().second){ mergedIntervals.back().second = max(e, mergedIntervals.back().second); }else{ mergedIntervals.emplace_back(s,e); } } long long coveredSum = 0; for(auto &[a,b] : mergedIntervals){ coveredSum += b-a; } return totalDistance - static_cast<int>(coveredSum); } // Example usage int main(){ vector<Light> data{{0,50},{100,60}}; cout << "Uncovered Length:" << calculateUnlitLength(data,200)<<endl; return 0; } ``` 此版本展示了如何用C++完成同样的逻辑操作。 --- #### Java 实现 ```java import java.util.*; class Solution { public static class Light { int position; int radius; public Light(int p, int r) { this.position = p; this.radius = r; } } public static int getUnlitLength(List<Light> lights, int totalDist) { List<int[]> ranges = new ArrayList<>(); for(Light l : lights){ int begin = Math.max(l.position - l.radius, 0); int finish = Math.min(l.position + l.radius, totalDist); ranges.add(new int[]{begin,finish}); } Collections.sort(ranges,(a,b)->Integer.compare(a[0],b[0])); LinkedList<int[]> mergedRanges = new LinkedList<>(); for(var range : ranges){ if (!mergedRanges.isEmpty() && mergedRanges.getLast()[1]>=range[0]){ mergedRanges.setLast(new int[]{ mergedRanges.getLast()[0], Math.max(range[1],mergedRanges.getLast()[1]) }); }else{ mergedRanges.addLast(range); } } int coverdTotal=0; for(var mrgRange : mergedRanges){ coverdTotal+=mrgRange[1]-mrgRange[0]; } return totalDist-coverdTotal; } public static void main(String[] args) { List<Light> list=new ArrayList<>(Arrays.asList( new Light(0,50), new Light(100,60))); System.out.println(getUnlitLength(list,200)); } } ``` 这段Java代码同样实现了路灯间无光区段测量功能。 --- #### JavaScript 实现 ```javascript function findDarkSpots(lights, totalRoadLen){ let segments=[]; // 构建各灯泡影响范围数组 for(let i of lights){ const lowerBound=Math.max(i.pos-i.rad,0); const upperBound=Math.min(i.pos+i.rad,totalRoadLen); segments.push([lowerBound,upperBound]); } // 排序以便后续合并 segments.sort((a,b)=>a[0]-b[0]); let combinedSegments=[segments.shift()]; while(segments.length!==0){ var nextSeg=segments.shift(); var lastCombined=combinedSegments.at(-1); if(nextSeg[0]<=lastCombined[1]){ lastCombined[1]=Math.max(lastCombined[1],nextSeg[1]); }else{ combinedSegments.push(nextSeg); } } let litArea=combinedSegments.reduce((acc,[from,to])=>acc+(to-from),0); return totalRoadLen-litArea; } const testLights=[ {"pos":0,"rad":50},{"pos":100,"rad":60}]; console.log(findDarkSpots(testLights,200)); // 输出应为40米 ``` 这是JavaScript版解决方案。 --- #### 总结 以上四种主流开发环境中的解答均遵循相同的核心理念——先求取单体光源作用域再综合评估整体遮蔽状况最后量化缺失比例。这种方法不仅适用于本题情境也广泛运用于其他涉及资源配优化等领域的问题之中^。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无限码力

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值