题解:AT_arc147_e [ARC147E] Examination

AT_arc147_e [ARC147E] Examination 题解

首先,考虑无解如何判定。将 ab 分别排序,排序后,有解的充要条件是始终满足 aibi

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

用堆实现。用两个小根堆分别存下 ai<bi 的元素的 ab;以 b 为第一关键字,用小根堆存下 aibi 的元素;用大根堆存下满足 bjai 的所有 aj 即可。

代码实现如下:

#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; }

__EOF__

本文作者NightTide
本文链接https://www.cnblogs.com/NightTide/p/18434002.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Night_Tide  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示