题解:洛谷 AT_abc465_b Parking 2
【题目来源】
洛谷:AT_abc465_b [ABC465B] Parking 2
【题目描述】
有一个停车场,收费规则如下:
- 在从 \(L\) 点整到 \(R\) 点整的时间段内,每停车一小时收费 \(X\)。
- 在上述时间段以外,每停车一小时收费 \(Y\)。
如果一辆车从 \(A\) 点整停车到 \(B\) 点整,并且没有跨越午夜,请问应该收取多少停车费?
【输入】
从标准输入读取,格式如下:
\(X\) \(Y\) \(L\) \(R\) \(A\) \(B\)
【输出】
输出答案。
【输入样例】
700 300 9 17 7 21
【输出样例】
7400
【核心思想】
-
问题分析:给定高峰时段 \([L, R]\) 每小时收费 \(X\),非高峰时段每小时收费 \(Y\),停车时段 \([A, B]\)(不跨午夜)。求总停车费。这是一个区间覆盖 + 分段计费问题,核心在于将一天 \(24\) 小时按高峰/非高峰分类,再对停车时段逐小时累加。
-
算法选择:
- 逐小时标记法:用数组 \(t[i]\) 记录第 \(i\) 小时(\(i\) 点到 \(i+1\) 点)的收费标准,先标记高峰时段,再对停车时段逐小时累加
-
关键步骤:
- 读入数据:读取 \(X, Y, L, R, A, B\)
- 初始化费率数组(\(i\) 从 \(1\) 到 \(23\)):\(t[i] \leftarrow Y\)(非高峰)
- 标记高峰时段(\(i\) 从 \(L\) 到 \(R-1\)):\(t[i] \leftarrow X\)
- 累加停车费(\(i\) 从 \(A\) 到 \(B-1\)):\(ans \leftarrow ans + t[i]\)
- 输出结果:\(ans\)
-
时间/空间复杂度:
- 时间复杂度:\(O(1)\),固定 \(24\) 小时的遍历
- 空间复杂度:\(O(1)\),固定大小的费率数组
-
逐小时标记与累加的核心思想:
- 离散时间建模:将连续时间离散化为 \(24\) 个整点区间,第 \(i\) 小时代表时间段 \([i, i+1)\),便于数组索引和逐小时计费
- 高峰时段的数组标记:\(t[L]\) 到 \(t[R-1]\) 标记为 \(X\),因为 \(L\) 点整到 \(R\) 点整包含的小时段是 \([L, L+1), [L+1, L+2), \ldots, [R-1, R)\),共 \(R-L\) 个区间
- 停车时段的对齐:停车从 \(A\) 点整到 \(B\) 点整,包含的小时段是 \([A, A+1), \ldots, [B-1, B)\),对应数组下标 \(A\) 到 \(B-1\)
- 不跨午夜的简化:题目保证不跨午夜,因此停车时段 \([A, B]\) 完全落在 \(1\) 到 \(24\) 范围内,无需处理日期边界
- 适用于基础区间覆盖、分段计费、时间离散化类入门问题
【算法标签】
入门 #模拟
【代码详解】
#include <bits/stdc++.h>
using namespace std;
int x, y, l, r, a, b; // x: 高峰时段每小时费用; y: 非高峰时段每小时费用
// l, r: 高峰时段起止时间; a, b: 停车起止时间
int t[30]; // t[i]: 第 i 小时(i点到i+1点)的收费标准
int main()
{
cin >> x >> y >> l >> r >> a >> b; // 读入所有参数
for (int i = 1; i <= 23; i++) // 初始化所有时段费用为 y(非高峰)
t[i] = y;
for (int i = l; i < r; i++) // 将 l 到 r-1 时段的费用设为 x(高峰)
t[i] = x;
int ans = 0; // ans: 累计总停车费
for (int i = a; i < b; i++) // 累加停车时段 a 到 b-1 的每小时费用
ans += t[i];
cout << ans << endl; // 输出总停车费
return 0;
}
【运行结果】
700 300 9 17 7 21
7400
浙公网安备 33010602011771号