MC0461排队
码蹄集OJ-排队
问题描述
唐僧师徒四人历经千辛万苦取得真经后,天庭决定为所有参与取经的众生灵举办一场庆功宴。然而,宴会入口处有 n
个生灵排队,每个生灵都提出了自己的 “站位要求”:
- 金蟾精型(
opt = 1
):“我前面至少有x
个生灵,否则我站不稳!” 即该生灵的位置pos
需满足pos >= x + 1
(排队位置从 1 开始计数 )。 - 紧箍咒型(
opt = 2
):“我前面至多有x
个生灵,否则我念咒头疼!” 即该生灵的位置pos
需满足pos <= x + 1
。 - 如来神掌型(
opt = 3
):“我前面至少有x
个生灵,至多有y
个生灵,否则我施展不开!” 即该生灵的位置pos
需满足x + 1 <= pos <= y + 1
。
若存在一种排队方式,使得所有生灵的要求都得到满足,请输出 Y
,否则输出 N
。
输入格式
- 第一行一个整数
T
(1 ≤ T ≤ 10^6
),表示测试数据组数。 - 对于每组测试数据:
- 第一行一个整数
n
(1 ≤ n ≤ 10^6
)。 - 接下来
n
行,每行第一个输入一个整数opt
(opt ∈ {1,2,3}
),如果opt = 1
或者opt = 2
,接着输入一个整数x
;否则如果opt = 3
,接着输入两个整数x, y
,数据满足:0 ≤ x, y < n
;分别表示每个生灵提出的要求。
- 第一行一个整数
- 数据保证:
∑n ≤ 10^6
。
输出格式
对于每组测试数据:输出一行一个字符 Y
或者 N
,表示答案。
样例 1
输入:
2
3
2 0
1 2
3 0 1
2
3 0 0
3 0 0
输出:
Y
N
代码:
#include<bits/stdc++.h>
using namespace std;int n;
struct node {int l, r;
} a[1000010]; // 用于 sort 的比较函数,按区间左端点升序排序
bool cmp(node a, node b)
{return a.l < b.l;
}void solve()
{cin >> n;int f = 1; for (int i = 1; i <= n; i++) { int op;cin >> op;if (op == 1) { int x;cin >> x;a[i].l = x + 1; a[i].r = n; } else if (op == 2) { int x;cin >> x;a[i].l = 1; a[i].r = x + 1; } else { int x, y;cin >> x >> y;a[i].l = x + 1; a[i].r = y + 1; if (x > y) { f = 0; }}}if (!f) { cout << "N\n";return;}// 按区间左端点排序sort(a + 1, a + n + 1, cmp); // 大顶堆,存储区间右端点,用于贪心选最小可行右端点priority_queue<int, vector<int>, greater<int>> q; for (int i = 1, j = 1; i <= n; i++) { // 将左端点 <= 当前位置 i 的区间,加入队列while (j <= n && a[j].l <= i) { q.push(a[j].r);j++;}if (!q.empty()) { if (q.top() >= i) { q.pop();}else { cout << "N\n";return;}} else { cout << "N\n";return;}}// 所有位置都成功分配cout << "Y\n";
}int main()
{// 加速输入输出cin.tie(0), cout.tie(0); int t;cin >> t; while (t--) { solve();}return 0;
}