停车场
来源:互联网 发布:如何做好美工 编辑:程序博客网 时间:2024/04/25 21:04
题目描述
刚拿到驾照的 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
样例输出
1
7
4
2
7
4
1
3
- 翻译一下题目,就是叫你把一个[1,n]的区间每次找到“最长”的那一段,输出那段的中间点(停车的位置),特殊判断[1,p]:停车在1 和 [q,n]:停车在n.
- 方法一:用线段树做,每次停车,将停车位置上的权值视为0,每次开走,将停车位置上的权值视为1. 用上传更新(我这样叫它:push_pu())的方法更新每段区间内的最长线段mx和最长线段的起始位置mxpos。为了更新最长线段,需要记录区间左端开始的最长线段lmx和右段开始的最长线段rmx。就像hotel那道题一样。特殊的是,最长线段mx不必再包含区间两端的lmx和rmx,因为并没什么用。最后Quary的时候要特殊判断。
- 方法二:用优先队列做,把停车后截成的小线段进队列,判断当前的最大线段是否合理用树状数组。在用链表记录一下车左右的车的位置,就差不多了。
#include<cstdio>#define MAXN 200000#define MAXNUM 2000000struct node{ int l,r; int lmx,rmx,mx,mxpos;}tree[MAXN*4+100];int n,m,car[MAXNUM+10];void build(int i,int l,int r){ tree[i].l=l,tree[i].r=r; tree[i].lmx=tree[i].rmx=tree[i].mx=r-l+1; tree[i].mxpos=l; if(l==r) return ; int mid=(l+r)/2; build(i*2,l,mid); build(i*2+1,mid+1,r);}int Weight(int len){ if(!len) return 0; return (len-1)/2+1;}void Adjust(int i,int len,int st){ if(!len) return ; int g=Weight(tree[i].mx),h=Weight(len); if(g<h) tree[i].mx=len,tree[i].mxpos=st; else if(g==h && st<tree[i].mxpos) tree[i].mxpos=st;}void push_up(int i){ tree[i].lmx=tree[i*2].lmx,tree[i].rmx=tree[i*2+1].rmx; if(tree[i].lmx==tree[i*2].r-tree[i*2].l+1) tree[i].lmx+=tree[i*2+1].lmx; if(tree[i].rmx==tree[i*2+1].r-tree[i*2+1].l+1) tree[i].rmx+=tree[i*2].rmx; //标记好mx=0,impossible;mx不用一并包含lmx和rmx tree[i].mxpos=0,tree[i].mx=0; Adjust(i,tree[i*2].rmx+tree[i*2+1].lmx,tree[i*2].r-tree[i*2].rmx+1); Adjust(i,tree[i*2].mx,tree[i*2].mxpos); Adjust(i,tree[i*2+1].mx,tree[i*2+1].mxpos);}void insert(int i,int inpos,int d){ if(tree[i].l==inpos && tree[i].r==inpos){ tree[i].lmx=tree[i].rmx=tree[i].mx=d; if(d) tree[i].mxpos=tree[i].l; else tree[i].mxpos=0; return ; } int mid=(tree[i].l+tree[i].r)/2; if(inpos<=mid) insert(i*2,inpos,d); else insert(i*2+1,inpos,d); push_up(i);}int Quary(){ int len=(tree[1].mx-1)/2+1,ret=(tree[1].mxpos*2+tree[1].mx-1)/2; if(tree[1].lmx>=len) ret=1; else if(tree[1].rmx>len) ret=n; return ret;}int main(){ int p,num,inpos; scanf("%d%d",&n,&m); build(1,1,n); for(int i=1;i<=m;i++){ scanf("%d%d",&p,&num); if(p==1){ inpos=Quary(); printf("%d\n",inpos); car[num]=inpos; insert(1,inpos,0); } else{ inpos=car[num]; insert(1,inpos,1); car[num]=0; } }}
错误代码:还不知道怎么错了!!!!!!!!
#include<cstdio>#define MAXN 200000#define MAXNUM 2000000struct node{ int l,r; int lmax,rmax,maxx,mxpos;}tree[MAXN*4+100];int n,m,car[MAXNUM+10];void build(int i,int l,int r){ tree[i].l=l,tree[i].r=r; tree[i].lmax=tree[i].rmax=tree[i].maxx=r-l+1; tree[i].mxpos=l; if(l==r) return ; int mid=(l+r)/2; build(i*2,l,mid); build(i*2+1,mid+1,r);}void revise(int i,int len,int pos){ tree[i].lmax=tree[i].rmax=tree[i].maxx=len; tree[i].mxpos=pos;}int Interval(node a){ return a.r-a.l+1;}int Weight(int l,int len){ if(!len) return -1; if(l==1) return len; if(l+len-1==n) return len; return (len-1)/2+1;}void Adjust(int i,int tmp,int tmpl){ int a=Weight(tree[i].mxpos,tree[i].maxx),b=Weight(tmpl,tmp); if(a<b) tree[i].maxx=tmp,tree[i].mxpos=tmpl; else if(a==b && tree[i].mxpos>tmpl) tree[i].mxpos=tmpl;}void insert(int i,int inpos,int d){ if(tree[i].l==inpos && tree[i].r==inpos){ if(d) revise(i,1,tree[i].l); else revise(i,0,0); return ; } int mid=(tree[i].l+tree[i].r)/2; if(inpos<=mid) insert(i*2,inpos,d); else insert(i*2+1,inpos,d); tree[i].lmax=tree[i*2].lmax,tree[i].rmax=tree[i*2+1].rmax; if(tree[i].lmax==Interval(tree[i*2])) tree[i].lmax+=tree[i*2+1].lmax; if(tree[i].rmax==Interval(tree[i*2+1])) tree[i].rmax+=tree[i*2].rmax; tree[i].maxx=tree[i].lmax; tree[i].mxpos=tree[i].l; Adjust(i,tree[i].rmax,tree[i].r-tree[i].rmax+1); Adjust(i,tree[i*2].rmax+tree[i*2+1].lmax,tree[i*2].r-tree[i*2].rmax+1); Adjust(i,tree[i*2].maxx,tree[i*2].mxpos); Adjust(i,tree[i*2+1].maxx,tree[i*2+1].mxpos);}int Quary(){ int len=(tree[1].maxx-1)/2+1,ret=(tree[1].mxpos*2+tree[1].maxx-1)/2; if(tree[1].lmax>=len) len=tree[1].lmax,ret=1; if(tree[1].rmax>len) ret=n; return ret;}int main(){ int p,num; scanf("%d%d",&n,&m); build(1,1,n); for(int i=1;i<=m;i++){ scanf("%d%d",&p,&num); if(p==1){ int pos=Quary(); printf("%d\n",pos); car[num]=pos; insert(1,pos,0); } else{ int pos=car[num]; insert(1,pos,1); car[num]=0; } }}
0 0
- 停车场
- 停车场
- 停车场
- 停车场
- 停车场
- 停车场
- 停车场
- 停车场
- 停车场收费
- 停车场~c++
- 停车场问题
- 停车场程序设计
- 停车场管理
- 停车场模拟
- 停车场模拟
- 停车场模拟
- 停车场模拟
- refersh停车场
- LigerUI_ligerGrid表格中复选框反选
- 使用httpclient下载图片时,url中含有中文字符,导致下载失败的解决方法
- 教育本来应该是什么样... 摘自百度百科>>周国平
- h5 video标签
- 数据绑定-1
- 停车场
- 欢迎使用CSDN-markdown编辑器
- SpringMVC整合WebSocket
- C++指针(一)
- C语言实现的Python扩展模块
- 自定义参数运行configure脚本
- struct和typedef struct的用法
- tableView footerView背景颜色
- C++ BOOST库 条件变量[多线程通信]机制 简单介绍