D. Parking Lot
time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Nowadays it is becoming increasingly difficult to park a car in cities successfully. Let's imagine a segment of a street as long as L meters along which a parking lot is located. Drivers should park their cars strictly parallel to the pavement on the right side of the street (remember that in the country the authors of the tasks come from the driving is right side!). Every driver when parking wants to leave for themselves some extra space to move their car freely, that's why a driver is looking for a place where the distance between his car and the one behind his will be no less than b meters and the distance between his car and the one in front of his will be no less than f meters (if there's no car behind then the car can be parked at the parking lot segment edge; the same is true for the case when there're no cars parked in front of the car). Let's introduce an axis of coordinates along the pavement. Let the parking lot begin at point 0 and end at point L. The drivers drive in the direction of the coordinates' increasing and look for the earliest place (with the smallest possible coordinate) where they can park the car. In case there's no such place, the driver drives on searching for his perfect peaceful haven. Sometimes some cars leave the street and free some space for parking. Considering that there never are two moving cars on a street at a time write a program that can use the data on the drivers, entering the street hoping to park there and the drivers leaving it, to model the process and determine a parking lot space for each car.

Input

The first line contains three integers L, b и f (10 ≤ L ≤ 100000, 1 ≤ b, f ≤ 100). The second line contains an integer n (1 ≤ n ≤ 100) that indicates the number of requests the program has got. Every request is described on a single line and is given by two numbers. The first number represents the request type. If the request type is equal to 1, then in that case the second number indicates the length of a car (in meters) that enters the street looking for a place to park. And if the request type is equal to 2, then the second number identifies the number of such a request (starting with 1) that the car whose arrival to the parking lot was described by a request with this number, leaves the parking lot. It is guaranteed that that car was parked at the moment the request of the 2 type was made. The lengths of cars are integers from 1 to 1000.

Output

For every request of the 1 type print number -1 on the single line if the corresponding car couldn't find place to park along the street. Otherwise, print a single number equal to the distance between the back of the car in its parked position and the beginning of the parking lot zone.

Sample test(s)
Input
30 1 2
6
1 5
1 4
1 5
2 2
1 5
1 4
Output
0
6
11
17
23
Input
30 1 1
6
1 5
1 4
1 5
2 2
1 5
1 4
Output
0
6
11
17
6
Input
10 1 1
1
1 12
Output
-1
Solution
模拟。
用pair<int,int>存空白区间,
用优先队列(priority queue)存(维护)所有空白区间。
这里有一个我遇到的问题:存(维护)何种空白区间。
显然有两种方案:
(1)存“实际”的空白区间,即(后车头/道路起点--前车尾/道路终点),停车时需考虑前后车距;
(2)存“可用”的空白区间,“可用”的含义是只要长度允许,车可在区间内任意停放,亦即不用考虑前后车距。
按方式(2),停车操作很方便实现,但离开操作就很麻烦(我在此处凌乱了,还没确认是否可做)。
按方式(1)则相反,但停车操作只是if-else,思路很清楚。
另外,还需要将当前活跃(active)区间用数组标记,将区间(a, b)记成 tail[a]=b, head[b]=a
 #include<bits/stdc++.h>
#define X first
#define Y second
#define set1(a) memset(a, -1, sizeof(a))
#define remove(a) head[tail[a]]=-1, tail[a]=-1
#define renew(a, b) tail[a]=b, head[b]=a
using namespace std;
typedef pair<int,int> pii;
pii r[];
int L, b, f, n;
void input(){
scanf("%d%d%d%d", &L, &b, &f, &n);
for(int i=; i<=n; i++)
scanf("%d%d", &r[i].X, &r[i].Y);
} priority_queue<pii, vector<pii>, greater<pii> > q;
stack<pii> s;
const int MAX_L=1e5+;
int head[MAX_L], tail[MAX_L];
int ans[];
void park(int i){
int len=r[i].Y;
ans[i]=-;
while(!q.empty()){
pii top=q.top();
q.pop();
if(tail[top.X]!=top.Y) continue;
if(top.X==){
if(top.Y==L){
if(L>=len){
ans[i]=;
remove();
if(L>len){
q.push(pii(len, L));
//printf("%d %d\n", len, L);
renew(len, L);
}
}
}
else if(top.Y>=len+f){
ans[i]=;
remove();
q.push(pii(len, top.Y));
renew(len, top.Y);
}
}
else if(top.Y>=top.X+b+len){
if(top.Y==L){
remove(top.X);
renew(top.X, top.X+b);
ans[i]=top.X+b;
if(L>top.X+b+len){
q.push(pii(top.X+b+len, L));
renew(top.X+b+len, L);
}
}
else if(top.Y>=top.X+b+len+f){
remove(top.X);
renew(top.X, top.X+b);
ans[i]=top.X+b;
q.push(pii(top.X+b+len, top.Y));
renew(top.X+b+len, top.Y);
}
}
if(~ans[i]) break;
s.push(top);
}
while(!s.empty())
q.push(s.top()), s.pop();
} void leave(int i){
int lb=ans[i], rb=lb+r[i].Y;
int tmp;
if(~head[lb]) lb=head[lb], remove(lb);
if(~tail[rb]) tmp=tail[rb], remove(rb), rb=tmp;  //error-prone
q.push(pii(lb, rb));
renew(lb, rb);
} void init(){
set1(head);
set1(tail);
q.push(pii(, L));
renew(, L);
} int main(){
//freopen("in", "r", stdin);
input();
init();
for(int i=; i<=n; i++)
if(r[i].X==) park(i), printf("%d\n", ans[i]);
else leave(r[i].Y);
return ;
}

P.S. 这道题的模拟也可以不用优先队列,用链表也行。

												

Codeforces 46D Parking Lot的更多相关文章

  1. ●CodeForces 480E Parking Lot

    题链: http://codeforces.com/problemset/problem/480/E题解: 单调队列,逆向思维 (在线的话应该是分治做,但是好麻烦..) 离线操作,逆向考虑, 最后的状 ...

  2. Codeforces 219E Parking Lot 线段树

    Parking Lot 线段树区间合并一下, 求当前要占的位置, 不包括两端点的写起来方便一点. #include<bits/stdc++.h> #define LL long long ...

  3. Codeforces Round #135 (Div. 2) E. Parking Lot 线段数区间合并

    E. Parking Lot time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...

  4. Codeforces 480.E Parking Lot

    E. Parking Lot time limit per test 3 seconds memory limit per test 256 megabytes input standard inpu ...

  5. 【26.8%】【CF 46D】Parking Lot

    time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standa ...

  6. Codeforces Parking Lot

    http://codeforces.com/problemset/problem/630/I 简单的排列组合,推式子技巧:举一个小样例,看着推,别抽象着推,容易错 #include <iostr ...

  7. Parking Lot CodeForces - 480E

    大意: 给定01矩阵, 单点赋值为1, 求最大全0正方形. 将询问倒序处理, 那么答案一定是递增的, 最多增长$O(n)$次, 对于每次操作暴力判断答案是否增长即可, 也就是说转化为判断是否存在一个边 ...

  8. Codeforces Round#415 Div.2

    A. Straight «A» 题面 Noora is a student of one famous high school. It's her final year in school - she ...

  9. CF 480 E. Parking Lot

    CF 480 E. Parking Lot http://codeforces.com/contest/480/problem/E 题意: 给一个n*m的01矩阵,每次可以将一个0修改为1,求最大全0 ...

随机推荐

  1. 6月27日 OGDF不同的布局算法

    检查不同布局算法 备注 CircularLayout 可以非连通 FastMultipoleMultilevelEmbedder    FMMMLayout   可以非连通 StressMajoriz ...

  2. 30Springd的包扫描——<context:component-scan base-package=” ”/>

    在context中配置 如:在base-package指明一个包: <context:component-scan base-package="cn.edu.dao"/> ...

  3. html的解析

    Web页面运行在各种各样的浏览器当中,浏览器载入.渲染页面的速度直接影响着用户体验 简单地说,页面渲染就是浏览器将html代码根据CSS定义的规则显示在浏览器窗口中的这个过程.先来大致了解一下浏览器都 ...

  4. 【转】【WPF】WPF 登录窗口关闭时打开主窗口

    在WPF中设计登录窗口关闭时打开主窗口,自动生成的App.xaml不能满足要求, 1.把App.xaml的属性窗口中的生成操作设定为 无 2.添加Program类 static class Progr ...

  5. 混合语言编程:启用CLR(公共语言运行时编译)让C#调用C++

    前言 关于混合C#和C++的编程方式,本人之前写过一篇博客(参见混合语言编程:C#使用原生的Directx和OpenGL),在之前的博客中,介绍了在C#的Winform和WPF下使用原生的Direct ...

  6. 移动APP为什么要开发两套Android和IOS-桥接模式

    一.前言 现在用H5开发个 web app 多么方便,兼容两大系统Andriod和IOS.但是为什么许多公司还要开发原生的APP?开发原生的APP就需要开发两套一套运行在Andriod系统的,一套运行 ...

  7. 从Lumia退役看为什么WP走向没落

    前段时间决定将自己用了三年多的Lumia 800正式退役,这是我用的时间最长的手机,虽然系统上有缺陷,但是好不妨碍他成为我最有感情的一部手机.由于之前是WinPhone 开发者的关系,这部手机是微软送 ...

  8. 如何用Android Studio打多包名APK

    问题:项目中不同的分发渠道可能需要打包多种APK(同样的代码),包名可能是不一样的,如果一个一个修改包名重新编apk是很麻烦,可以参考下列步骤在Android Studio上操纵Gradle来打包不同 ...

  9. php模式设计之 适配器模式

    在这个有没有对象都要高呼“面向对象”的年代,掌握面向对象会给我们带来意想不到的方便.学编程的小伙伴从开始能写几行代码实现简单功能到后来懂得将一些重复的操作组合起来形成一个“函数”,再到后来将“函数”和 ...

  10. sql server 清空数据库表数据

    --禁用外键约束 exec   sp_msforeachtable   'alter   table   ?   nocheck   constraint   all ' --清空数据 truncat ...