Codeforces Gym100187C Very Spacious Office 贪心 堆
原文链接https://www.cnblogs.com/zhouzhendong/p/CF-Gym100187C.html
题目传送门 - CF-Gym100187C
题意
给定 $n$ 个房间以及 $n$ 个人。
第 $i$ 个房间的大小为 $a_i$。
第 $i$ 个人要的房间的大小范围为 $[L_i,R_i]$ 。
现在给每一个人安排房间,一个房间只能被一个人拥有。
问是否存在方案满足条件。
如果不存在,输出:Let's search for another office.
如果存在多种方案,输出:Ask Shiftman for help.
否则输出:Perfect! 并在第二行输出 $n$ 个数,第 $i$ 个数表示给第 $i$ 个人分配的房间编号。
题解
首先我们不考虑多种解的情况。
做法是个简单贪心。
我们将房间按照 $a_i$ 升序排序。
将人的需求按照 $L_i$ 升序排序。
然后从左到右依次处理每一个房间。
对于房间 $i$ ,我们从 $L$ 比他小的所有还没有被匹配的人中找到 $R_j$ 最小的(这个可以用一个堆来实现)。
如果 $R_j<a_i$ 那么由于未匹配的房间中最小的就是 $a_i$,所以这个人一定无法匹配了,所以无解。
否则让房间 $i$ 匹配第 $j$ 个人。显然让 $R_i$ 尽量小的先匹配时最优的。
这样可以得到一组解。
然后我们考虑如何判断是否多解。
假设我们已经有了一个解。
则,当且仅当下面的条件满足时,存在多解。
条件: 存在两个人,选择的房间都在他们两个人都可以接受的范围内。
于是我们要考虑如何来搞这个。
考虑对于当前人选择的当前房间。我们找到满足“选择的房间比当前房间小的,可以接受的区间比当前房间大的”人中选择的房间尽量大的,判断这两个人的房间是否可以交换。如果有解,并至少存在一组这样的人,那么为多解。这个东西显然可以再用个堆搞定。
代码
#include <bits/stdc++.h>
using namespace std;
const int N=100005;
int n,a[N],b[N];
struct Node{
int a,id;
}v[N];
struct Seg{
int L,R,id;
Seg(){}
Seg(int _L,int _R){L=_L,R=_R;}
friend bool operator < (Seg a,Seg b){
return a.R>b.R;
}
}s[N];
int res[N];
bool cmpL(Seg a,Seg b){return a.L<b.L;}
bool cmpid(Seg a,Seg b){return a.id<b.id;}
bool cmpa(Node a,Node b){return a.a<b.a;}
priority_queue <Seg> Q,Q2;
int main(){
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",&v[i].a),v[i].id=i;
sort(v+1,v+n+1,cmpa);
v[0].a=0,v[n+1].a=1e9+1;
for (int i=0;i<=n+1;i++)
a[i]=v[i].a,b[n+1-i]=1e9+1-v[i].a;
for (int i=1;i<=n;i++){
scanf("%d%d",&s[i].L,&s[i].R);
s[i].id=i;
s[i].L=lower_bound(a,a+n+2,s[i].L)-a;
s[i].R=n+1-(lower_bound(b,b+n+2,1e9+1-s[i].R)-b);
// printf("%d %d\n",s[i].L,s[i].R);
}
while (!Q.empty())
Q.pop();
while (!Q2.empty())
Q2.pop();
sort(s+1,s+n+1,cmpL);
bool flag=0;
for (int i=1,j=1;i<=n;i++){
while (j<=n&&s[j].L<=i)
Q.push(s[j++]);
if (Q.empty()){
puts("Let's search for another office.");
return 0;
}
Seg now=Q.top();
Q.pop();
if (now.R<i){
puts("Let's search for another office.");
return 0;
}
res[now.id]=v[i].id;
while (!Q2.empty()){
Seg Now=Q2.top();
if (Now.L<i){
Q2.pop();
continue;
}
if (now.L<=n-Now.R)
flag=1;
break;
}
Q2.push(Seg(now.R,n-i));
}
if (flag){
puts("Ask Shiftman for help.");
return 0;
}
puts("Perfect!");
for (int i=1;i<=n;i++)
printf("%d ",res[i]);
return 0;
}
Codeforces Gym100187C Very Spacious Office 贪心 堆的更多相关文章
- 【贪心+堆】XMU 1584 小明的烦恼
题目链接: http://acm.xmu.edu.cn/JudgeOnline/problem.php?id=1584 题目大意: 给n(n<=100 000)个任务的耗时和截至时间,问最少不能 ...
- BZOJ_2151_种树_贪心+堆+链表
BZOJ_2151_种树_贪心+堆 Description A城市有一个巨大的圆形广场,为了绿化环境和净化空气,市政府决定沿圆形广场外圈种一圈树.园林部门得到指令后,初步规划出n个种树的位置,顺时针编 ...
- BZOJ_2006_[NOI2010]超级钢琴_贪心+堆+ST表
BZOJ_2006_[NOI2010]超级钢琴_贪心+堆+ST表 Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的 音乐 ...
- BZOJ_1029_ [JSOI2007]建筑抢修_贪心+堆
BZOJ_1029_ [JSOI2007]建筑抢修_贪心+堆 Description 小刚在玩JSOI提供的一个称之为“建筑抢修”的电脑游戏:经过了一场激烈的战斗,T部落消灭了所有z部落的入侵者.但是 ...
- 【bzoj4425】[Nwerc2015]Assigning Workstations分配工作站 贪心+堆
题目描述 佩内洛普是新建立的超级计算机的管理员中的一员. 她的工作是分配工作站给到这里来运行他们的计算研究任务的研究人员. 佩内洛普非常懒惰,不喜欢为到达的研究者们解锁机器. 她可以从在她的办公桌远程 ...
- 【bzoj1029】[JSOI2007]建筑抢修 贪心+堆
题目描述 小刚在玩JSOI提供的一个称之为“建筑抢修”的电脑游戏:经过了一场激烈的战斗,T部落消灭了所有z部落的入侵者.但是T部落的基地里已经有N个建筑设施受到了严重的损伤,如果不尽快修复的话,这些建 ...
- 【bzoj2802】[Poi2012]Warehouse Store 贪心+堆
题目描述 有一家专卖一种商品的店,考虑连续的n天.第i天上午会进货Ai件商品,中午的时候会有顾客需要购买Bi件商品,可以选择满足顾客的要求,或是无视掉他.如果要满足顾客的需求,就必须要有足够的库存.问 ...
- codeforces Gym 100338E Numbers (贪心,实现)
题目:http://codeforces.com/gym/100338/attachments 贪心,每次枚举10的i次幂,除k后取余数r在用k-r补在10的幂上作为候选答案. #include< ...
- BZOJ 1724: [Usaco2006 Nov]Fence Repair 切割木板 贪心 + 堆 + 反向思考
Description Farmer John想修理牧场栅栏的某些小段.为此,他需要N(1<=N<=20,000)块特定长度的木板,第i块木板的长度为Li(1<=Li<=50, ...
随机推荐
- bootstrap DataTable绑定数据带服务器分页
<!-- DataTables --> 这两个文件在我的文件夹里面<script src="~/bower_components/datatables.net/js/jq ...
- 浅谈深度优先和广度优先(scrapy-redis)
首先先谈谈深度优先和广度优先的定义 深度优先搜索算法(英语:Depth-First-Search,DFS)是一种用于遍历或搜索树或图的算法.沿着树的深度遍历树的节点,尽可能深的搜索树的分支.当节点v的 ...
- centos6.5 Python.7 pip install PIL --allow-external PIL --allow-unverified PIL报错 no such option: --allow-external
解决办法 pip install pillow 使用from PIL import Image ,正常!!
- jq获取页面url后边带的参数
//获取url后边的参数 $.getUrlParam = function (name) { var reg = new RegExp("(^|&) ...
- 2。创建第一个angular应用,已经开发前的一些配置
现在我们开始新建一个angular5的脚手架 . 到想要建项目的目录下.比如我的 在 D:\JsProjects 进入cmd或者powershell cd 进入该文件夹下 然后开始新建,ng ne ...
- js之DOM对象三
一.JS中for循环遍历测试 for循环遍历有两种 第一种:是有条件的那种,例如 for(var i = 0;i<ele.length;i++){} 第二种:for (var i in ...
- Python基础之面向对象进阶一
一.isinstance(obj,cls)和issubclass(sub,super) 1.isinstance(obj,cls)检查obj是否是类 cls 的对象 class A: pass obj ...
- Web Penetration Testing w3af fierce
1.启动wsaf工具,设置载入插件(攻击模型的插件),可以设置默认的攻击模型,也可以添加自己的plug. 2.在侦查的时候渗透邮箱需要知道,云行邮箱服务的托管服务器是什么类型,在之前的博客中我已近两提 ...
- Niagara物联网框架机制二(笔记)
一.Niagara框架 1.一个Niagara 系统中有四种典型的Programs,这些程序间的关系及其网络通讯关系可通过下面的通讯图表解释 2. Niagara Programs station ...
- appium 手势
1.2 appium玩转安卓手机 智能手机发展到今天,形成了一整套有关手势操作的操作习惯,如手指左右上下滑动,及双指缩放,还有手指的滑动解锁,摇晃手机等动作.那么我们怎么在python中利用appiu ...