寒假作业2:简化电梯设计elevator
Github仓库地址:hua-kui
寒假学习计划:学习计划
- 题目背景
一栋10层的大楼(楼层编号1-10),设有一台无限载重的电梯,初始时电梯停在1层。电梯移动1层的耗时为1,在某一层停靠的耗时为1(时间初始为0)。为了使得乘客等待的时间(电梯在目的层的停靠时刻 - 乘客发出请求时刻)总和最小,请你编写一个程序来进行电梯调度。
输入有5个请求,每个请求一行,格式为请求时刻 起始楼层数 去往方向,其中方向为0代表向上去往10层,为1代表向下去往1层。
输出每次对应的决策,每一行的输出格式为xx时,停靠在x楼。其中,“xx时刻”指的是在某层楼停靠的时刻,且不算入在该层的停靠时间。如:
- 当0时刻时,电梯此时在1层,输入有0 1 0,那么电梯从1层接客(1s)前往10层(9s),应输出10时,停靠在10楼(1+9=10)。此时,该乘客等待时间为(10-0=)10。
- 当0时刻,电梯此时在1层,输入有0 2 0,那么电梯从1层前往2层(1s),接上乘客(1s),前往10层(8s),应输出10时,停靠在10楼(1+1+8=10)。此时,该乘客等待时间为(10-0=)10s。
最后输出完成5个请求(所有乘客都到达目的地)后,各乘客的等待时间总和。
ANS 1
- 代码情况
| 代码长度 | bug | 耗时 |
|---|---|---|
| 175行 | 13处 | 12~14h |
- 分析
EMMM先看这个题目虽然觉得能随时变换方向还不消耗时间的电梯有点魔幻hhh(关注点不要在这里啦!)
好了看到没有时间的限制和其他的要求,我脑海里第一个跳出的就是暴搜(毕竟暴力出奇迹OTL)那么再来看数据点,经过简单分析,很明显,排除了某些213乘客会走楼梯的情况,那么大多数乘客只会在原地等待,因此,停靠在别的楼层是很显然没有意义的,如此一来,电梯只会在我们请求的地点(5个)+1楼+10楼停靠,当然,5个地点中也有可能会重复……
好啦接下来看数据构造w
- 数据模型
- 关于乘客
struct{
int time;//记录这名乘客发出请求的时刻
int ceng;//记录这名乘客发出请求的层数
int flag;//记录这名乘客去的方向 0表示向下,1表示向上
int zhuang;//记录这名乘客的状态 0表示等待进入,1表示在电梯中,2表示已经下电梯
int value;//记录这名乘客的到达时间:到达的时间-发出请求的time
}r[1004];
这个结构体是乘客的信息记录,其中value是我第一次算时间的时候太213了(其实是太弱)构造出来的,结果写起来非常麻烦也没有必要,想了好久,后来发现其实只要算电梯当前时间-乘客请求时间=等待时间就可以了,也就是在1楼和10楼进行统计
- 关于电梯
struct {
int time;//记录当前的时间
int floor;//电梯当前所在的楼层
int flag;//记录现在取得方向,有0 10两种
}dt;
这个东西实在DFS中记录实时情况的,对他进行更新,也就是所等待的时间即
abs(dt.time-r[i].time)再+1S+1S+1S(简直续命游戏)
这样后面的+1S可以在每次停靠的时候模拟处理+1S
- 数据更新
- 关于更新写了3个处理,也就是在1楼、10楼、和其他请求楼层
10楼
if(n==10)
for(int i=1;i<=5;i++)
if(r[i].flag==1&&r[i].zhuang==1)
{
r[i].zhuang=2;
}//如果当前是第10层,让电梯中需要出去的人出去
而1楼、和其他楼层依次类推,只需要让需要下车的人下车,需要上的人更新就行,需要注意的一点是我之前没有考虑到的,在之后回溯的时候,需要还原,而就需要开个数组记录这些下车或上车的人,把他们再还原丢出去。
- 最终目标
- 我们搜到的最终目标也就是让所有人的状态都变成2,也就是到达目的地为止,这样所有的请求都已经应答
- 实现
- 如此一来我们就可以根据上面的几个构造直接暴搜DFS遍历最优解,也就是第K次决策,停靠在……最后取最少时间
void dfs(int k){//第K次决策
int ji=0;
for(int i=1;i<=7;i++)//一个时刻有7种可能可以停靠,因为只会停靠在有人请求的楼层
{
if(i!=6&&i!=7&&r[i].zhuang==0)//如果不是1、10楼且还有未应答的人员
{
ji=dt.floor;//记录楼层
dt.time+=abs(dt.floor-r[i].ceng);
dt.floor=r[i].ceng;//模拟电梯移动
ans[k].time=dt.time;
ans[k].floor=dt.floor;//数据更新
for(int j=1;j<=5;j++)
if(r[j].ceng==r[i].ceng&&r[j].zhuang==0)
{
r[j].zhuang=1;
ask[j]=1;//如果当前停靠的层数有人要上,那就让他进入电梯
}
if(pd()==1)
pd2(t);//进行判断 :是否到达目标节点
else
dfs(k+1);//搜索下一策略
dt.time-=abs(dt.floor-r[i].ceng);
dt.floor=ji; //回溯回复
for(int j=1;j<=5;j++)
if(ask[j]==1)
{
r[j].zhuang=0;
}
for(int j=1;j<=5;j++)
ask[j]=0;//回溯回复,也就是上述的开一个记录,把进入的乘客丢出去
}
}
这是普通楼层的处理方式,而1、10楼的方式类似,但需要判断的地方更多,如:回溯时的复原等等(一开始就是这些小点全没有考虑到,然后……、死循了)
- 辛酸的心路历程(BUG处理)
爱之初体验
之前第一次没认真看的时候觉得还行,就是模拟,后来发现细节有一点多……(哭的像个两百斤的狗子、、特别是+1S的续命游戏一开始没有加上去)
一开始写的时候是定义成为第K时刻的决策,后来又更改成为第K层是否停留,把1-10层全遍历一边
爱之再选择
- 最终排除了刚开始的想法,推倒重新来,更改了核心语句,新开设了一个电梯的信息的记录组,用来统计实时状态,变为第K次决策,也就是第K步应该向哪里走。
- 细节的初始化和回溯……开了比较多的东西记录,一些边界还有初始化的修改出了比较大的问题,反复都在改这个
- 上面有提到的那个统计时间一开始纠结了好久,没有想到怎么去更新把时间弄上去,所以才会开了一个VALUE来记录,后来发现不用,因为电梯的信息也是要记录的,就减一下就OK
- 0 和 1也就是1和10写反了……找了好久
爱之最终题
- 为了更新电梯的实时情况,还写了一个调用函数,即
void gx(int n)//用来更新电梯中人员的状态,n表示当前层数
{
if(n==10)
for(int i=1;i<=5;i++)
if(r[i].flag==1&&r[i].zhuang==1)
{
r[i].zhuang=2;
}//如果当前是第10层,让电梯中需要出去的人出去
if(n==1)
for(int i=1;i<=5;i++)
if(r[i].flag==0&&r[i].zhuang==1)
{
r[i].zhuang=2;
}//如果当前是第1层,让电梯中需要出去的人出去
for(int i=1;i<=5;i++)
if(r[i].ceng==n&&r[i].zhuang==0)
r[i].zhuang=1;//如果当前停靠的层数有人要上,那就让他进入电梯
}
也就是当电梯门开了之后进行更新,后来发现调用这个函数的时候可能会对回溯恢复带来比加大的麻烦,因此就更改了写法,不用上述的函数。
- 写完了之后发现出了上述的BUG与思考,还存在一些情况,那就是当一个比较久后的时间,比如前4个数据都是在1-20秒内做出请求,而第5个请求是在100秒时,当前4名乘客已经下站,做为一架未卜先知的电梯,应当做出他的选择,即:预先到所在地点等候。这又是一种特殊的情况因此添加了进去。
- 当然还存在一些情况,例如当第10层会不会有人发出请求,出了又进……(虽然这是很213的行为好吧)
- PS:还会不断优化 ,在处理某些数据的时候还可能会有未知BUG等
- 数据构造
- 第一类 顶层和底层
0 10 1 1 1 0
0 10 1 1 10 1
0 10 1 1 1 0
0 1 0 1 10 1
0 1 0 1 10 1

符合数据要求
- 第二类 正常小数据
0 4 0 0 1 0
0 5 0 1 10 1
0 6 0 2 1 0
0 7 0 3 5 1
0 8 0 4 6 1

符合数据要求
- 第三类 随机大数据时刻
4565 4 1 8742 1 0
4343 5 1 2345 9 1
5533 9 1 2323 1 0
1232 9 0 3565 5 1
3232 8 0 3323 6 1

符合数据要求
- 第四类 请求时刻大于运行时间
0 4 1 99 1 0
0 5 1 1 9 1
0 9 1 2 1 0
0 9 0 5 5 1
99 8 0 11 6 1

出现BUG:分析,超过运行时间回溯时出现错误
- 第五类 随机数据(出现重复楼层)
0 7 1 99 9 0
66 5 1 1 9 1
0 8 1 2 9 0
0 6 0 5 5 1
99 8 0 11 6 1

出现BUG:分析,第一个 99 9 0数据超出运行时间,回溯出现错误
ANS 2
做为不是一个未卜先知的电梯(虽然ANS 1中提前知道5个请求有点细思恐极),只需要按照5个请求顺推模拟即可,需要考虑的细节也是挺多的emmm
ANS 3
现实生活中的电梯:在群上看到有同学讨论现实生活中的两部并列电梯的运作方式(显然不会未卜先知和突然掉头),还挺有兴趣的,有想法的同学可以在下面评论留言或者私聊一起讨论呀~
Pintia小作业

寒假作业2:简化电梯设计elevator的更多相关文章
- Q114寒假作业之割绳子
割绳子 TimeLimit:1000MS MemoryLimit:10000K 64-bit integer IO format:%lld Problem Description 已知有n条绳子,每 ...
- 【集美大学1411_助教博客】团队作业2——需求分析&原型设计 成绩
首先要向各位同学道歉,最近助教的工作较多,并且伴随着频繁的出差,评论博客和评分都不及时,以致于同学们都没有得到反馈,在此我要表示歉意.其次,对于第二次团队作业,有两个团队没有提交到班级博客中但按时完成 ...
- 【1414软工助教】团队作业2——需求分析&原型设计 得分榜
题目 团队作业2--需求分析&原型设计 作业提交情况情况 本次作业所有团队都按时提交作业. 往期成绩 个人作业1:四则运算控制台 结对项目1:GUI 个人作业2:案例分析 结对项目2:单元测试 ...
- 进阶篇:4.1)DFA设计指南:简化产品设计(kiss原则)
本章目的:理解kiss原则,明确如何简化产品的设计. 1.前言:kiss原则,优化产品的第一原则 如果要作者选出一个优化产品的最好方法,那一定是kiss原则莫属.从产品的整体设计到公差的分析,kiss ...
- Luogu P2717 寒假作业(平衡树)
P2717 寒假作业 题意 题目背景 \(zzs\)和\(zzy\)正在被寒假作业折磨,然而他们有答案可以抄啊. 题目描述 他们共有\(n\)项寒假作业.\(zzy\)给每项寒假作业都定义了一个疲劳值 ...
- 寒假作业---蓝桥杯---DFS
题目描述 现在小学的数学题目也不是那么好玩的. 看看这个寒假作业: 每个方块代表1~13中的某一个数字,但不能重复. 比如: 6 + 7 = 13 9 - 8 = 1 3 * 4 = 12 10 ...
- java 寒假作业
寒假作业 现在小学的数学题目也不是那么好玩的. 看看这个寒假作业: □ + □ = □ □ - □ = □ □ × □ = □ □ ÷ □ = □ (如果显示不出来,可以参见[图1.jpg]) 每个方 ...
- 2016蓝桥杯省赛C/C++A组第六题 寒假作业
题意:现在小学的数学题目也不是那么好玩的. 看看这个寒假作业: □ + □ = □ □ - □ = □ □ × □ = □ □ ÷ □ = □ 每个方块代表1~13中的某一个数字,但不能重复. 比如: ...
- java实现第七届蓝桥杯寒假作业
题目6.寒假作业 寒假作业 现在小学的数学题目也不是那么好玩的. 看看这个寒假作业: □ + □ = □ □ - □ = □ □ × □ = □ □ ÷ □ = □ (如果显示不出来,可以参见[图1. ...
随机推荐
- Nginx与Tomcat实现请求动态数据与请求静态资源的分离
上篇博客说明了Nginx在应用架构中的作用,以及负载均衡的思路.这篇实践一下其中的访问静态资源与访问动态资源的操作. 一.认识访问静态资源与访问动态资源的区别 静态资源:指存储在硬盘内的数据,固定的数 ...
- js如何获取键盘高度
在移动端或混合app开发中,js如何获取键盘高度,直接贴上代码吧 input是一个html input 标签 var timer = { id:null, run:function (callback ...
- P2P借款人信用风险实时监控模型设计
P2P借款人信用风险实时监控模型设计 P2P网络贷款(“peer-to-peer”)为中小企业和个人提供了便利的融资渠道.近年来,随着互联网金融的逐步发展,P2P网贷已成为时下炙手可热的互联网金融新模 ...
- 嵌入式C语言自我修养 06:U-boot镜像自拷贝分析:section属性
6.1 GNU C 的扩展关键字:attribute GNU C 增加一个 __atttribute__ 关键字用来声明一个函数.变量或类型的特殊属性.声明这个特殊属性有什么用呢?主要用途就是指导编译 ...
- 海思平台交叉编译curl支持SSL功能
1.准备工具 1).交叉编译工具 2).下载libcurl和openssl源代码,我使用的是(openssl-1.0.2o.tar,curl-7.59.0.tar) 3).查看cpu详细 ~ # ca ...
- Linux IO多路复用 poll
Linux IO多路复用 poll 之前曾经提到过 select poll 跟select类似,poll改进了select的一个确定,就是poll没有监听上限 不过poll还是需要遍历以及频繁的把数组 ...
- Go语言反射之值反射
1 概述 反射不仅可以获取值的类型信息,还可操作变量的值.使用 reflect.Value 类型操作变量的值. 2 值反射对象 reflect.ValueOf() 方法可以获取一个值的反射对象,之后可 ...
- dedecms 顶级栏目内容显示
在需要的位置,添加: {dede:sql sql='Select content from dede_arctype where id=1'} [field:content/] {/dede:sql}
- echarts 拐点添加图片
series : [ { name:'搜索引擎', type:'line', symbol:'emptyCircle', symbolSize: 5, itemStyle: { normal: { l ...
- BZOJ1096_仓库建设_KEY
题目传送门 一道斜率优化的题目,加深了印象. 设sum[i]=∑p[i],S[i]=∑p[i]*x[i]. 暴力方程加前缀和优化: f[i]=min(f[j]+c[i]+(sum[i]-sum[j]) ...