📝鹅鸭杀

题型:贪心+优先队列 难度:夯 2026-05-08

📖 题目大意

有 n 个人,每个人只有在当前人数 ∈ [lᵢ, rᵢ] 时才愿意加入。你可以自由安排顺序,问最多能加入多少人,并输出任意一种顺序。

❗ 解题思路

⚙️ AC 代码(待补充)

#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin >> n;
    int l, r;
    vector<array<int, 3>> a;
    for (int i = 1; i <= n; i++) {
        cin >> l >> r;
        a.push_back({l, r, i});
    }
    sort(a.begin(), a.end()); // 按 l 排序

    priority_queue<array<int, 2>, vector<array<int, 2>>, greater<array<int, 2>>> q;
    vector<int> nums(n + 1, 0);
    int next = 0, cnt = 0;

    while (true) {
        while (next < n && a[next][0] <= cnt) {
            q.push({a[next][1], a[next][2]});
            ++next;
        }
        if (q.empty()) break;
        while (!q.empty()) {
            auto [r, id] = q.top(); q.pop();
            if (cnt > r) continue;
            nums[id] = ++cnt;
            break;
        }
    }

    vector<array<int, 2>> tmp;
    for (int i = 1; i <= n; ++i) {
        if (nums[i] != 0) tmp.push_back({nums[i], i});
    }
    sort(tmp.begin(), tmp.end());

    cout << tmp.size() << '\n';
    for (size_t i = 0; i < tmp.size(); ++i) {
        if (i) cout << ' ';
        cout << tmp[i][1];
    }
    cout << '\n';

    return 0;
}

📎 备注:本题易错点 / 心得

  • 选错编译器:必须选 C++17(支持结构化绑定)或 C++11+(需手动拆解)。
  • 输出格式:第一行人数,第二行编号(空格分隔),不能挤在一行。
  • 优先队列:必须是小根堆 greater<>,否则贪心错误。
  • 自增:安排时用 ++cnt(前缀),不能用 cnt++
  • 变量名统一:如 next 不要写成 netx
  • 循环边界for i=1 to n 包含 ≤n,否则漏人。

📚 今日总结


← 返回我的学习主页 第3天 /span>