1 条题解
-
0
算法标签
- 数据结构:有序集合 (set/平衡树)
- 模拟
- 贪心
- 区间处理
题目分析
这是一个典型的动态座位选择问题,需要维护当前被占用的座位集合,并在每次有新乘客进入时,快速找到距离其他乘客最远的空座位。
关键观察
- 座位布局特殊:只有2列,N行,这大大简化了问题
- 距离计算:欧几里得距离,但由于只有2列,最近距离通常来自同一行或相邻行的已占座位
- 选择策略:最大化最小距离,具有贪心性质
高效解法
核心思路
使用有序集合(如C++的
set)维护当前被占用的座位(按行号排序)。对于每个新乘客:- 处理边界情况:如果电车为空,直接返回(1,1)
- 生成候选座位:考虑所有相邻已占座位之间的区间
- 评估候选:在每个区间中,最优点通常出现在区间中点附近
- 选择最优:比较所有候选座位,选择距离最大的
算法步骤
#include <iostream> #include <set> #include <vector> #include <cmath> #include <algorithm> using namespace std; // 计算两个座位间的距离 double dist(int r1, int c1, int r2, int c2) { return sqrt((r1 - r2) * (r1 - r2) + (c1 - c2) * (c1 - c2)); } int main() { int N, M; cin >> N >> M; set<pair<int, int>> occ; // 被占用的座位 (行, 列) // 添加虚拟边界座位,便于处理第一个和最后一个区间 occ.insert({0, 1}); occ.insert({N + 1, 1}); vector<pair<int, int>> seatOf(M + 1); // 记录每个事件对应的座位 for (int k = 1; k <= M; k++) { char type; cin >> type; if (type == 'E') { // 电车为空的情况 if (occ.size() == 2) { seatOf[k] = {1, 1}; occ.insert({1, 1}); cout << "1 1\n"; continue; } double bestDist = -1; pair<int, int> bestSeat = {-1, -1}; // 遍历所有相邻的已占座位对(形成区间) auto it1 = occ.begin(); auto it2 = occ.begin(); ++it2; while (it2 != occ.end()) { int r1 = it1->first, c1 = it1->second; int r2 = it2->first, c2 = it2->second; // 区间 [r1+1, r2-1] 内的空座位 if (r1 + 1 <= r2 - 1) { // 检查区间中点附近的几行 int mid = (r1 + r2) / 2; for (int r = max(r1 + 1, mid - 2); r <= min(r2 - 1, mid + 2); r++) { for (int col = 1; col <= 2; col++) { if (occ.count({r, col})) continue; // 计算到最近已占座位的距离 double minD = 1e9; for (auto &p : occ) { double d = dist(r, col, p.first, p.second); if (d < minD) minD = d; } // 更新最优座位 if (minD > bestDist + 1e-9 || (abs(minD - bestDist) < 1e-9 && (r < bestSeat.first || (r == bestSeat.first && col < bestSeat.second)))) { bestDist = minD; bestSeat = {r, col}; } } } } ++it1; ++it2; } seatOf[k] = bestSeat; occ.insert(bestSeat); cout << bestSeat.first << " " << bestSeat.second << "\n"; } else { // 类型 L:乘客离开 int p; cin >> p; occ.erase(seatOf[p]); // 从占用集合中移除座位 } } return 0; }复杂度分析
- 时间复杂度:平均 O(M × K),其中 K 是平均的已占座位数
- 空间复杂度:O(M) 存储座位信息
- 1
信息
- ID
- 5596
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者