寒假作业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. ...
随机推荐
- django 登录注册注销
一.设计数据模型 1.数据库模型设计 作为一个用户登录和注册项目,需要保存的都是各种用户的相关信息.很显然,我们至少需要一张用户表User,在用户表里需要保存下面的信息: 用户名 密码 邮箱地址 性别 ...
- vue-cli 项目安装失败 tunneling socket could not be established, cause=connect ECONNREFUSED
1.安装vue-cli npm install vue-cli -g 2.初始化项目 vue init webpack project 此时报错:vue-cli · Failed to downloa ...
- 格式化输出%02hhx
每次看到人家的十六进制输出,对齐的很好,ff就显示了,而我的总是0xffffffff.如果是"%02x",是以0补齐2位数,如果超过2位就显示实际的数:"%hhx&quo ...
- Vim Go开发环境搭建
基本搭建流程参考了网上的博文以及Vimgo的Github主页 博文https://www.cnblogs.com/breg/p/5386365.html Vim-go主页(我能不能加入项目,做点贡献呢 ...
- leetcode记录-字符串转整数
实现 atoi,将字符串转为整数. 该函数首先根据需要丢弃任意多的空格字符,直到找到第一个非空格字符为止.如果第一个非空字符是正号或负号,选取该符号,并将其与后面尽可能多的连续的数字组合起来,这部分字 ...
- C# 访问修饰符和const、readonly
今天被人问起const和readonly,竟然有点咬不准,复习一遍. 访问修饰符 public 公有访问.不受任何限制. private 私有访问.只限于本类成员访问,子类,实例都不能访问. prot ...
- 2017-2018-1 20155318 《信息安全系统设计基础》第2周课堂实践、makefile、以及myod
2017-2018-1 20155318 <信息安全系统设计基础>第2周课堂实践.makefile.以及myod 测试3-gdb测试 用gcc -g编译vi输入的代码 在main函数中设置 ...
- 20155328 2016-2017-2 《Java程序设计》 第一周学习总结
20155328 2016-2017-2 <Java程序设计> 第一周学习总结 教材学习内容总结 本周学习目标是浏览<Java学习笔记>中的十八章,其中第一章和第二章认真学习, ...
- iOS 影音新格式 HEIF HEVC
苹果在 iOS 11 的发布会上,推出了两种新的媒体格式 HEIF HEVC,都是为了保证画质的情况下,大大减少视频.照片的大小. 一.简介 HEVC全称 High Efficiency Video ...
- bzoj1011 遥远的行星
bzoj1011 遥远的行星 原题链接 题解 一道真正的玄学题.... 其实这题根本没法做 首先暴力这么跑:\[ans(s)=\sum_{i=1}^{\lfloor As\rfloor}\frac{M ...