找回密码
 立即注册
查看: 12|回复: 0

洛谷P2190题解:铁路售票系统车厢计算(差分数组+前缀和优化)

[复制链接]
  • 打卡等级:即来则安
  • 打卡总天数:23
  • 打卡月天数:11
  • 打卡总奖励:152
  • 最近打卡:2025-07-15 14:27:44

26

主题

0

回帖

4516

积分

VIP会员

积分
4516
发表于 2025-7-5 18:27:20 | 显示全部楼层 |阅读模式
一、题目解读
洛谷P2190题要求解决铁路售票系统中的车厢数量计算问题。题目给定n个车站和m条订票申请,每条申请包含区间[x,y)及乘客数z。需要计算在不超载的情况下(每节车厢最多36人),满足所有乘客需求所需的最小车厢数。问题关键在于高效处理区间修改与统计**值。
二、解题思路
核心思路是利用差分数组+前缀和实现区间修改的优化。通过差分数组记录每个站点的乘客变化(如进入/离开人数),再计算前缀和得到各站点的实时乘客数,从而找出**值。特别处理环形区间(即x>y时,拆分为两段处理),确保逻辑完整性。
三、解题步骤
1. 输入与初始化:读入n、m,创建长度为n+2的差分数组(多留两端便于边界处理)。
2. 处理订票申请:
○ 普通区间(x≤y):在x位置+乘客数z,y位置-乘客数z(差分核心)。
○ 环形区间(x>y):拆分为两段:[x,n]和[1,y),分别差分处理。
3. 计算前缀和:遍历差分数组,累加当前值并更新**乘客数。
4. 计算车厢数:根据36人/车厢的规则,向上取整得到最终结果。
四、代码与注释
  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. using namespace std;

  5. int main() {
  6.     int n, m;  
  7.     cin >> n >> m;  

  8.     // 差分数组,记录每个站点的乘客变化  
  9.     vector<int> diff(n + 2, 0);  

  10.     // 处理每条订票申请  
  11.     for (int i = 0; i < m; ++i) {  
  12.         int x, y, z;  
  13.         cin >> x >> y >> z;  

  14.         if (x <= y) {  
  15.             // 普通区间[x,y)  
  16.             diff[x] += z;  
  17.             diff[y] -= z;  
  18.         } else {  
  19.             // 环形区间[x,n]和[1,y)  
  20.             diff[x] += z;  
  21.             diff[n+1] -= z;  
  22.             diff[1] += z;  
  23.             diff[y] -= z;  
  24.         }  
  25.     }  

  26.     // 计算前缀和,找出**乘客数  
  27.     int max_passengers = 0;  
  28.     int current = 0;  
  29.     for (int i = 1; i <= n; ++i) {  
  30.         current += diff[i];  
  31.         max_passengers = max(max_passengers, current);  
  32.     }  

  33.     // 计算所需车厢数(每节36人)  
  34.     int carriages = (max_passengers + 35) / 36;  
  35.     cout << carriages << endl;  

  36.     return 0;  
  37. }
复制代码


五、总结
本解法通过差分数组巧妙转化区间修改为单点操作,结合前缀和高效求解**值,时间复杂度O(n+m)。掌握此类“差分思想”对处理动态区间问题至关重要。代码简洁且逻辑清晰,为同类问题提供了优秀模板。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表