题目描述

刚拿到驾照的KJ 总喜欢开着车到处兜风,玩完了再把车停到阿Q的停车场里,虽然她对自己停车的水平很有信心,但她还是不放心其他人的停车水平,尤其是Kelukin。于是,她每次都把自己的爱车停在距离其它车最远的一个车位。KJ 觉得自己这样的策略非常科学,于是她开始想:在一个停车场中有一排车位,从左到右编号为 1 到 n,初始时全部是空的。有若干汽车,进出停车场共 m 次。对于每辆进入停车场的汽车,会选择与其它车距离最小值最大的一个车位,若有多个符合条件,选择最左边一个。KJ 想着想着就睡着了,在她一旁的Kelukin想帮她完成这个心愿,但是他又非常的懒,不愿意自己动手,于是就把这个问题就留给了你:在KJ 理想的阿 Q 的停车场中,给你车辆进出的操作序列,依次输出每辆车的车位编号。

输入格式

第一行,两个整数 n 和 m,表示停车场大小和操作数;

接下来 m 行,每行两个整数,F 和 x

F 是 1 表示编号为 x 的车进停车场;

F 是 2 表示编号为 x 的车出停车场;

保证操作合法,即:

出停车场的车一定目前仍在停车场里;

停车场内的车不会超过 n;

输出格式

对于所有操作 1,输出一个整数,表示该车车位的编号。

样例输入

7 11 
1 15 
1 123123 
1 3 
1 5 
2 123123 
2 15 
1 21 
2 3 
1 6 
1 7 
1 8

样例输出








3

数据范围

对30%的数据 n<=1000 ,m<=1000 
对60%的数据 n<=200000,m<=2000 
对100%的数据n,m<=200000,车的编号小于等于 10^6

思路

30%  

  第一边做打了一个爆搜,维护停车场和距离最大值两个数组,进出车辆各自维护,进车的时候两个指针分别指向左右端点,维护值即为原值和更新值中较小的;出车的时候因为不知道此时的值是谁赋给它的,所有把空车位全部填满重来一遍。

const ma=;

var f:array[..ma] of longint;
a:array[..ma] of longint;
n,m,k,x,y,num,ss,kk:longint; function min(x,y:longint):longint;
begin
if x<y then exit(x) else exit(y);
end; procedure intt;
begin
assign(input,'park.in');
assign(output,'park.out');
reset(input);
rewrite(output);
end; procedure outt;
begin
close(input);
close(output);
end; function update1(x:longint):longint;
var i,j,k,sum,num:longint;
begin
i:=x;j:=x;
while i>= do
begin
if a[i]= then
f[i]:=min(f[i],abs(x-i));
dec(i);
end;
while j<=n do
begin
if a[j]= then
f[j]:=min(f[j],abs(x-j));
inc(j);
end;
num:=;sum:=;
for i:= to n do
if (a[i]=)and(f[i]>sum) then
begin
sum:=f[i];
num:=i;
end;
exit(num);
end;
//car in function update2(x:longint):longint;
var i,j,num,sum:longint;
begin
for i:= to n do
if a[i]= then f[i]:=;
for i:= to n do
if a[i]<> then
for j:= to n do
if a[j]= then
f[j]:=min(f[j],abs(i-j));
num:=;sum:=;
for i:= to n do
if (a[i]=)and(f[i]>sum) then
begin
sum:=f[i];
num:=i;
end;
exit(num);
end;
//car out begin
intt;
fillchar(f,sizeof(f),);
fillchar(a,sizeof(a),);
readln(n,m);
for k:= to m do
begin
readln(x,y);
if k= then
begin
a[]:=y;
writeln();
ss:=update1();
continue;
end;
if x= then
begin
writeln(ss);
a[ss]:=y;
f[ss]:=;
ss:=update1(ss);
continue;
end;
if x= then
begin
for kk:= to n do
if a[kk]=y then
begin
a[kk]:=;
f[kk]:=;
ss:=update2(kk);
break;
end;
continue;
end;
end;
outt;
end.

45% 

  XYD维护了某车两侧的空车位,我也不知道是怎么维护的,反正也是爆搜。

program dddlk;
var a,l,r:array[..]of longint;
f:array[..]of boolean;
b:array[..]of longint;
n,m,i,j,a1,a2,ans,b1,max,b2:longint;
begin
assign(input,'park.in');
assign(output,'park.out');
reset(input);
rewrite(output);
ans:=;
read(n,m);
a[]:=-;
a[n+]:=-;
l[]:=-;
r[n+]:=;
for i:= to n do
a[i]:=maxlongint;
for i:= to m do
begin
read(a1,a2);
if a1=
then
begin
writeln(ans);
b[a2]:=ans;
f[ans]:=true;
a[ans]:=;
r[ans]:=ans;
l[ans]:=ans;
b1:=ans-;
while(b1>)and(not f[b1])do
begin
if a[b1]>ans-b1
then a[b1]:=ans-b1;
r[b1]:=ans;
dec(b1);
end;
b1:=ans+;
while(b1<n+)and(not f[b1])do
begin
if a[b1]>b1-ans
then a[b1]:=b1-ans;
l[b1]:=ans;
inc(b1);
end;
max:=a[];
ans:=;
for j:= to n do
if a[j]>max
then
begin
max:=a[j];
ans:=j;
end;
end
else
begin
b2:=b[a2];
b1:=b2-;
f[b2]:=false;
while(b1>)and(not f[b1])do
begin
r[b1]:=r[b2+];
if b1-l[b1]>r[b1]-b1
then a[b1]:=r[b1]-b1
else a[b1]:=b1-l[b1];
dec(b1);
end;
b1:=b2+;
while(b1<n+)and(not f[b1])do
begin
l[b1]:=l[b2-];
if b1-l[b1]>r[b1]-b1
then a[b1]:=r[b1]-b1
else a[b1]:=b1-l[b1];
inc(b1);
end;
l[b2]:=l[b2-];
r[b2]:=r[b2+];
if b2-l[b2]>r[b2]-b2
then a[b2]:=r[b2]-b2
else a[b2]:=b2-l[b2];
max:=a[];
for j:= to n do
if a[j]>max
then
begin
max:=a[j];
ans:=j;
end;
end;
end;
close(input);
close(output);
end.

60%

  不晓得这个怎么搞

100%

  用线段树实现。(据某位大神说,可以用堆来做。然而我并不会)用线段树还是相对简单的。首先我们对区间[1..n]开一课线段树。对于每一个节点,维护4个值。分别是l,r,mid,p。l表示在当前结点线段树所在区间,最左边的车停的位置。同理,r表示做右边的车所停的位置。mid表示在这个小区间[l,r]中的紧邻的两辆车的最长距离除以2后的值。p表示取得mid值是所在的紧邻的两辆车的中间位置,也就是在[l,r]中的答案值。

  对于 1 询问:访问线段树的第一个节点,我们比较l-1,n-r,mid的值哪个更大,就选哪个,它们的答案依次是1,n,mid。假设我们求得的位置是car[x]。然后访问[car[x],car[x]]所在的线段树的叶子节点,初始化它的值,然后回溯,进行合并。对于h[x].l与h[x].r可以通过两个儿子的l,r信息得出。对于h[x].mid值,首先在左右儿子的mid值中去一个最大的值。其次考虑一种情况,就是夹在两个线段之间的距离,可以通过(h[x+x+1].l-h[x+x].r) div 2 的值得出在于mid进行比较,然后p就随着mid的值的更新而更新。 
对于2询问:访问询问车所在的位置,直接将它的叶子节点[car[x],car[x]]删除,然后回溯时,再做一次合并操作。即可

AC做法:http://blog.csdn.net/liuyuanzhe0515/article/details/47414221

const   maxc=;maxn=;
type node=record
l,r,mid,p:longint;
end;
var i,j,k,m,n,ch,num,sum:longint;
car:array[..maxc] of longint;
h:array[..*maxn] of node;
procedure merger(x:longint);
var t:longint;
begin
if h[x+x].l> then h[x].l:=h[x+x].l else h[x].l:=h[x+x+].l;
if h[x+x+].r> then h[x].r:=h[x+x+].r else h[x].r:=h[x+x].r;
h[x].mid:=h[x+x].mid;
h[x].p:=h[x+x].p;
if (h[x+x+].l>) and (h[x+x].r>) then begin
t:=(h[x+x+].l-h[x+x].r) div ;
if t>h[x].mid then begin
h[x].mid:=t;
h[x].p:=(h[x+x+].l+h[x+x].r) div ;
end;
if h[x+x+].mid>h[x].mid then begin
h[x].mid:=h[x+x+].mid;
h[x].p:=h[x+x+].p;
end;
end;
end;
procedure work(x,l,r,num,kind:longint);
var mid:longint;
begin
if l=r then begin
if kind= then begin
h[x].l:=;h[x].r:=;
h[x].mid:=;h[x].p:=;
end else begin
h[x].l:=l;h[x].r:=r;
h[x].mid:=;h[x].p:=;
end;
exit;
end;
mid:=(l+r)>>;
if num<=mid then work(x+x,l,mid,num,kind) else work(x+x+,mid+,r,num,kind);
merger(x);
end;
begin
readln(n,m);
for i:= to m do begin
readln(ch,num);
if ch= then begin
if h[].l= then begin
car[num]:=;
end else begin
sum:=-maxlongint;
if h[].l->sum then begin
sum:=h[].l-;
car[num]:=;
end;
if h[].mid>sum then begin
sum:=h[].mid;
car[num]:=h[].p;
end;
if n-h[].r>sum then begin
sum:=n-h[].r;
car[num]:=n;
end;
end;
writeln(car[num]);
work(,,n,car[num],);
end else begin
work(,,n,car[num],);
end;
end;
end.

[GRYZ2015]阿Q的停车场的更多相关文章

  1. 2017-11-8 NOIP模拟赛

    1.足球联赛 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm ...

  2. 2017.11.8 Noip2017 考前模拟赛

    ----------------------------------T1---------------------------------- ——>足球联赛 题目描述 巴蜀中学新一季的足球联赛开 ...

  3. IGS_学习笔记03_Integrated SOA Gateway设定配置(案例)

    20150506 Created By BaoXinjian

  4. SDUT -refresh的停车场(栈和队列)

    题目描写叙述  refresh近期发了一笔横財,开了一家停车场.因为土地有限,停车场内停车数量有限,可是要求进停车场的车辆过多. 当停车场满时,要进入的车辆会进入便道等待.最先进入便道的车辆会优先 进 ...

  5. refresh的停车场(栈和队列的STL)

    refresh的停车场 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描写叙述  refresh近期发了一笔横財,开了一家停车场. 因 ...

  6. SDUT OJ 2088 refresh的停车场

    refresh的停车场 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述  refresh最近发了一笔横财,开了一家停车场.由于土地 ...

  7. C语言实现简单的停车场管理系统

    问题描述:停车场是一个能放n辆车的狭长通道,只有一个大门,汽车按到达的先后次序停放.若车场满了,车要停在门外的便道上等候,一旦有车走,则便道上第一辆车进入.当停车场中的车离开时,由于通道窄,在它后面呢 ...

  8. SDUT-2088_数据结构实验之栈与队列十一:refresh的停车场

    数据结构实验之栈与队列十一:refresh的停车场 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description refresh最近发 ...

  9. S7-300位逻辑指令仿真练习 停车场

    第三章 S7-300 指令应用 位逻辑指令 M存储器 在PLC中M存储区(也称位存储区,又称内部存储器标志位(M)存储器区),它属于系统存储区.在你选定具体的CPU型号后,可以查看CPU的技术规格,其 ...

随机推荐

  1. 信息化的“五观”与“N为”

    系统观:联系的总体的看 生产力工具观:人与工具关系 马克思政治经济学 辨证观:发展的看 技术观:第一生产力  改变生产生活(生存)方式 信息论观:“人”联网 控制论 工程观:群体合作的智力游戏论

  2. Notepad++ 书签

      Notepad++,有一个书签功能,指定书签是Ctrl+F2,在书签之间移动是按F2来切换,这个可以在几个想查看的数据之间进行快速切换,所以看起来就很方便.

  3. ExtJS4.2学习(九)属性表格控件PropertyGrid(转)

    鸣谢网址:http://www.shuyangyang.com.cn/jishuliangongfang/qianduanjishu/2013-11-15/178.html ------------- ...

  4. 弹窗开关js

    // var guanbi = false; // $("#testbtn").click(function(){ // if(guanbi){ // $("#tan&q ...

  5. 纯CSS制作二级导航

    一.问题描述 做一个类似校园网首页,主要是导航栏的设置,ul默认纵向排列,如何横向排列,同时去掉圆点. 二.问题解决 2.1 先写导航条 用两个ul嵌套,一个ul是横向导航条,另一个是每个小项目下连一 ...

  6. Window8 进不了PE如何设置BIOS

    如题,如今进入Win8时代,很多新出的机器都自带了WIN8.但是童鞋们想进PE进行操作的时候,发现进不了. 更改BIOS以下2处设置,即可使用第三方引导安装系统:Boot->Launch CSM ...

  7. Top命令内存占用剖析

    原文: http://yalung929.blog.163.com/blog/static/203898225201212981731971/ 引 言: top命令作为Linux下最常用的性能分析工具 ...

  8. 186. Reverse Words in a String II

    题目: Given an input string, reverse the string word by word. A word is defined as a sequence of non-s ...

  9. Python之函数篇

    函数形参 函数取得的参数是你提供给函数的值,这样函数就可以利用这些值 做 一些事情.这些参数就像变量一样,只不过它们的值是在我们调用函数的时候定义的,而非在函数本身内赋值. 参数在函数定义的圆括号对内 ...

  10. strlen的C/C+++实现

    2013-07-05 11:36:05 小结: 本函数给出了几种strlen的实现,有ugly implementation,也有good implementation.并参考标准库中的impleme ...