寒假作业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. ...
随机推荐
- RedirectAttributes 之 IE8请求跳转失败
1.时间真快,一晃又快冬天了,下了第一场雪.雪花漫漫,堵车悠悠. 2.这次遇到这样一个问题,就是RedirectAttributes传递数据参数,如果参数数据过大,在IE8浏览器时候会跳转不过去.其实 ...
- 关于flume的filechannel的 full 问题
事务启动以后,批量向事务Transaction的一个putList的尾部写入,putlist是一个LinkedBlockingDeque . 事务提交的时候, 把putlist中的event批量移除, ...
- Python使用__slots__限制实例属性
#定义一个类Student class Student(object): __slots__ = ('name','age') #用元组(tuple)的形式绑定属性名称 s = Student() s ...
- Docker CPU Usage
背景 当一台机器上跑有多个 Docker Container 的时候,我们需要知道,哪些容器占用了多少资源.采集这些指标,来让我们可以更加好的分配资源给每个 Container. 获取容器CPU使用率 ...
- # 20155337 2016-2017-2 《Java程序设计》第九周学习总结
20155337 2016-2017-2 <Java程序设计>第九周学习总结 教材学习内容总结 第16章 JDBC(Java DataBase Connectivity)即java数据库连 ...
- OpenCV人脸识别-训练级联分类器
OpenCV中以及附带了训练好的人脸特征分类器,3.2版本的有三种: 分别是LBP,Haar,Hug 在Data目录下. 也可以训练自己的特征库,具体参照如下: 级联分类器训练 — OpenCV 2. ...
- 4040 EZ系列之奖金 (拓扑)
4040 EZ系列之奖金 时间限制: 1 s 空间限制: 64000 KB 题目等级 : 钻石 Diamond 题目描述 Description 由于无敌的WRN在2015年世界英俊帅 ...
- cogs2554 [福利]可持久化线段树
cogs2554 [福利]可持久化线段树 原题链接 每次修改复制一遍就行了... 1A!!! // It is made by XZZ #include<cstdio> #include& ...
- centos7下python3与python2共存并且开启py3虚拟环境
因为下载视频需要用到python3环境,今天在我的win上安装下载工具死活安装不上去,在大盘鸡上一下就安装成功了...可能在win上不兼容吧...无奈只能在大盘鸡上进行折腾了,顺便几个笔记 由于大盘鸡 ...
- sqlite两表更新update
1 2 3 4 5 6 7 8 9 10 11 12 UPDATE t1 SET Column1 = ( SELECT Columnx FROM t2 WHERE t2. KEY = ...