题解:AT_arc147_e [ARC147E] Examination

AT_arc147_e [ARC147E] Examination 题解

首先,考虑无解如何判定。将 \(a\)\(b\) 分别排序,排序后,有解的充要条件是始终满足 \(a_i \ge b_i\)

首先 \(a_i < b_i\) 的人必然需要调整,将它们塞入一个集合 \(S\) 中。首先内部调整,将 \(S\) 内的 \(a\)\(b\) 排序。然后开始遍历,若某时刻仍存在 \(a_i < b_i\) 的情况,则需要其他元素来调整。那么我们必须要加入一个 \(b_j \le a_i < a_j\) 的人才能满足条件。贪心地想,我们显然优先选择 \(a_j\) 最大的。

用堆实现。用两个小根堆分别存下 \(a_i < b_i\) 的元素的 \(a\)\(b\);以 \(b\) 为第一关键字,用小根堆存下 \(a_i \ge b_i\) 的元素;用大根堆存下满足 \(b_j \le a_i\) 的所有 \(a_j\) 即可。

代码实现如下:

#include<bits/stdc++.h>
#define MAXN 300010
using namespace std;
struct node{ int a, b; };
bool operator > (node p, node q){ return p.b > q.b; }
bool operator < (node p, node q){ return p.b < q.b; }
int n, cnt;
node stu[MAXN];
int tmp_a[MAXN], tmp_b[MAXN];
priority_queue<node, vector<node>, greater<node> > t;
priority_queue<int, vector<int>, greater<int> > qa, qb;
priority_queue<int, vector<int>, less<int> > s;
int main(){
    scanf("%d",&n);
    for(int i = 1; i <= n; i++) scanf("%d%d",&stu[i].a,&stu[i].b);
    for(int i = 1; i <= n; i++) tmp_a[i] = stu[i].a, tmp_b[i] = stu[i].b;
    sort(tmp_a + 1, tmp_a + n + 1);
    sort(tmp_b + 1, tmp_b + n + 1);
    for(int i = 1; i <= n; i++){
        if(tmp_a[i] < tmp_b[i]){
            printf("-1\n");
            exit(0);
        }
    }
    for(int i = 1; i <= n; i++){
        if(stu[i].a < stu[i].b) qa.push(stu[i].a), qb.push(stu[i].b);
        else t.push(stu[i]);
    }
    while(!qa.empty()){
        cnt++;
        int ta = qa.top(), tb = qb.top();
        if(ta >= tb){
            qa.pop(); qb.pop();
            continue;
        }
        while(!t.empty() && t.top().b <= ta){
            s.push(t.top().a);
            t.pop();
        }
        qa.pop(); qa.push(s.top()); s.pop();
    }
    printf("%d\n",n - cnt);
    return 0;
}
posted @   Night_Tide  阅读(11)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示