1.题目情景

我们假设都是从一楼上电梯的,而至于讯电梯停在其中的某一层。即所有的乘客都从一楼上电梯,到达某层之后,电梯停下来,所有乘客再从这里爬楼梯到自己的目的层。在一楼的时候,每个乘客选择自己的目的层,电梯则自动计算出应停的楼层,并且能够保证该层停使得所有乘客爬楼梯的层数之和最少。

输入:第一行楼层数N,乘客人数n;第二行有n个数,表示乘客选择的目的层。

输出:输出为停止楼层和总共需要爬的楼梯。

2.解法一

第一种方法就是采取暴力求解的办法,采用双重循环的方式,外循环控制停的楼层,内循环计算当前楼层停,总共需要爬多少楼层,并保留最小值及其相应停电梯的楼层。

具体代码如下:

package bianchengzhimei.part1_8;

import java.util.*;

public class ElevatorController {

public static void main(String[] args) {

// TODO Auto-generated method stub

Scanner sc=new Scanner(System.in);

int N=sc.nextInt();

int n=sc.nextInt();

int passenger[]=new int[n];

for(int i=0;i

{

passenger[i]=sc.nextInt();

}

int stopFloor=0;

int minFloor=Integer.MAX_VALUE;

for(int i=1;i<=N;i++)//控制停电梯的楼层

{

int temp=0;

for(int j=0;j

{

temp+=Math.abs(passenger[j]-i);

}

if(temp

{

minFloor=temp;

stopFloor=i;

}

}

System.out.println("最佳停电梯的楼层为:"+stopFloor);

System.out.println("乘客需要爬楼梯的总数为:"+minFloor);

sc.close();

}

}

运行结果如下:

10 6

4 8 3 9 10 5

最佳停电梯的楼层为:5

乘客需要爬楼梯的总数为:15

这种方法比较简单直接,因此复杂度较高,为O(N*n),所以接下来我们想办法降低复杂度。如果n大于N,那么可以将上述程序做一些修改也可以稍微降低复杂度。当n大于N时,先计算N层楼每层楼有几个乘客,复杂度为O(n),然后再遍历,遍历过程复杂度为O(N*N),因此下面程序总复杂度为O(n+N*N)。

package bianchengzhimei.part1_8;

import java.util.*;

public class ElevatorController {

public static void main(String[] args) {

// TODO Auto-generated method stub

Scanner sc=new Scanner(System.in);

int N=sc.nextInt();

int n=sc.nextInt();

int passenger[]=new int[N+1];

for(int i=0;i

{

passenger[sc.nextInt()]+=1;

}

int stopFloor=0;

int maxFloor=Integer.MAX_VALUE;

for(int i=1;i<=N;i++)//控制停电梯的楼层

{

int temp=0;

for(int j=1;j<=N;j++)//计算停在当前楼层,总共需要爬的楼层

{

temp+=Math.abs(j-i)*passenger[j];

}

if(temp

{

maxFloor=temp;

stopFloor=i;

}

}

System.out.println("最佳停电梯的楼层为:"+stopFloor);

System.out.println("乘客需要爬楼梯的总数为:"+maxFloor);

sc.close();

}

}

3.解法二

我们假设停在第i层楼,那么当前楼层需要爬的总楼层是Y。如果有N1个乘客在楼层i以下,有N2个乘客在第i层楼,还有N3个乘客在第i层以上。那么如果现在电梯停在i-1层,则总共需要爬Y-N1+(N2+N3)层,如果改在i+1层,那么总共需要爬Y-N3+(N2+N1)层,所以我们可以换个思路,当电梯从一楼逐渐往上走的时候,当N2+N1-N3<0时,则继续往上爬,当当N2+N1-N3>=0,则可以停下来,因为往上爬的过程中N3是逐渐减小的,一旦N2+N1-N3>=0之后,那么随着楼层往上爬,这个差值会越来越大,即代表人们要爬的总楼层越来越多,所以当差值不再为负即可停下来。

实现代码如下:

package bianchengzhimei.part1_8;

import java.util.Scanner;

public class ElevatorController2 {

public static void main(String[] args) {

// TODO Auto-generated method stub

Scanner sc=new Scanner(System.in);

int N=sc.nextInt();

int n=sc.nextInt();

int Floor[]=new int[N+1];//用来统计每个楼层停下的人数

for(int i=0;i

Floor[sc.nextInt()]+=1;

sc.close();

int stopFloor=1;//先从第一层开始推算

int N1=0;//停在第一层的话,第一层是最低的,那么N1则为0

int N2=Floor[1];//假设第一次停在第一层,求出目标楼层是当前楼层的人数.

//计算N3的初始值和停在1层对应的nMinFloor值

int N3=0;

int nMinFloor=0;

for(int i=2;i<=N;i++)

{

N3+=Floor[i];

nMinFloor+=Floor[i]*(i-1);

}

//然后逐渐往上走,寻找最优目标楼层。

for(int i=2;i<=N;i++)

{

if(N1+N2-N3<0)//即判断往上走,爬楼梯总数是否会减少。

{

N1+=N2;

N2=Floor[i];

N3-=Floor[i];

stopFloor=i;//更新停电梯楼层.

nMinFloor+=(N1+N2-N3);//更新爬楼梯总数

}

else

break;

}

System.out.println("最佳停电梯的楼层为:"+stopFloor);

System.out.println("乘客需要爬楼梯的总数为:"+nMinFloor);

}

}

以上解法是从第一层往上走,依次更新相应的数据,直到目标值不能再优化时,得到最优值。运行结果如下:

10 6

4 8 3 9 10 5

最佳停电梯的楼层为:5

乘客需要爬楼梯的总数为:15

4.解法三

其实,还有一种解法,有n个乘客都有自己需要去的楼层,在停止楼层下电梯之后,大家都要去自己的目标楼层,那么我们假设每位乘客都已经在目的楼层了,那么我们可以将问题转换为,所有乘客在哪一层碰头,所需要爬的楼梯最少。一般这种会面算法,最佳地点应该选择在中间数,即将每一位乘客所在位置,放进一个数组并排序取中间数就是最佳会面地点。(注:当乘客数为n,则最佳地点就是有序地点集合中第(n+1)/2个元素代表的地点)。其中这里的排序可以用桶排序,因为楼层数不会过于庞大,那么把每一层都当做一个桶,然后把相应的人放进去,桶号即数组下标,然后逐个取出就完成了排序,复杂度是线性的。

package bianchengzhimei.part1_8;

import java.util.Scanner;

public class ElevatorController3 {

private static int[] calSort(int[] a,int N,int n)

{

int[] res=new int[n];

int k=0;

for(int i=0;i<=N;i++)

{

int temp=a[i];

while(temp>0)

{

res[k++]=a[i];

}

}

return res;

}

public static void main(String[] args) {

// TODO Auto-generated method stub

Scanner sc=new Scanner(System.in);

int N=sc.nextInt();

int n=sc.nextInt();

int passenger[]=new int[N+1];

for(int i=0;i

{

passenger[sc.nextInt()]+=1;

}

sc.close();

int[] res=calSort(passenger,N,n);//桶排序

int stopFloor=res[(n+1)/2-1];

int nMinFloor=0;

for(int i=1;i<=N;i++)

{

nMinFloor+=(i-stopFloor)*passenger[i];

}

System.out.println("最佳停电梯的楼层为:"+stopFloor);

System.out.println("乘客需要爬楼梯的总数为:"+nMinFloor);

}

}

运行结果:

10 8

1 1 2 7 8 8 8 9

最佳停电梯的楼层为:7

乘客需要爬楼梯的总数为:22

---------------------

作者:carson0408

来源:CSDN

原文:https://blog.csdn.net/carson0408/article/details/79184859

版权声明:本文为博主原创文章,转载请附上博文链接!

java 电梯算法_编程之美之小飞的电梯调度算法(多种解法)---Java语言相关推荐

  1. java python算法_用Python,Java和C ++示例解释的排序算法

    java python算法 什么是排序算法? (What is a Sorting Algorithm?) Sorting algorithms are a set of instructions t ...

  2. java多线程电梯调度_面向对象之多线程(可捎带电梯调度)

    面向对象之多线程(可捎带电梯调度) 1. 题目重述 ​本题完成的任务为多部多线程可捎带调度电梯的模拟,电梯系统具有的功能为:上下行.开关门.新增一部可以使用的电梯,电梯系统在某一层开关门时间内可以上下 ...

  3. java 线性回归算法_线性搜索或顺序搜索算法在Java中如何工作? 示例教程

    java 线性回归算法 大家好,之前,我讨论了二进制搜索算法的工作原理,并分享了在Java中实现二进制搜索的代码. 在那篇文章中,有人问我是否还有其他搜索算法? 如果数组中的元素未排序,又该如何使用它 ...

  4. java python算法_用Java,Python和C ++示例解释的搜索算法

    java python算法 什么是搜索算法? (What is a Search Algorithm?) This kind of algorithm looks at the problem of ...

  5. c和java哪个好学_编程入门学习c++和Java哪个比较好

    编程入门学习c++和Java哪个比较好 发布时间:2020-04-25 16:54:41 来源:亿速云 阅读:231 作者:栢白 编程入门学习c++和Java哪个比较好?如今这些都是小白比较关心的,如 ...

  6. java轮训算法_负载均衡算法WeightedRoundRobin(加权轮询)简介及算法实现

    Nginx的负载均衡默认算法是加权轮询算法,本文简单介绍算法的逻辑,并给出算法的Java实现版本. 算法简介 有三个节点{a, b, c},他们的权重分别是{a=5, b=1, c=1}.发送7次请求 ...

  7. jsp中java代码无效_来杯咖啡,教你如何优雅的在java中统计代码块耗时

    推荐阅读: Sping源码+Redis+Nginx+MySQL等七篇实战技术文档,阿里大佬推荐 阿里内部:2020年全技术栈文档+PPT分享,(万粉总结,回馈粉丝) 在我们的实际开发中,多多少少会遇到 ...

  8. 最大公约数(gcd)和最小公倍数(lcm)的多种解法 Java 实现

    下面总共介绍了四种最大公约数的求解方法和一个最小公倍数的求解方法 该代码的视频讲解 [300题刷题挑战]leetcode力扣 最大公约数和最小公倍数的多种解法 GCDandLCM第八十三题 | 数学方 ...

  9. 24点游戏java代码 中国开源社区_编程之美 1.16 24点游戏

    24点游戏大家都知道:4张牌,可以进行+ - * / 四种运算,可以使用括号,每个牌用一次,任意组合构造表达式使结果为24. 扩展问题:n个整数,四种运算,可使用括号,每个数字使用一次,使表达式结果为 ...

最新文章

  1. Office安装时报错1907的解决方法
  2. protoc-3.2.0-win32转java文件
  3. ASP.NET之一般处理程序笔记
  4. **上海铁路局2004年最新时刻发布!**
  5. wordpress archive.php,哪个网址将导致wordpress使用archive.php?
  6. php 父类中获取子类的名称,php – 在父类中获取子类的名称(静态上下文)
  7. GConf error:Failed to contact configuration server
  8. 光信噪比 (OSNR) 的概念及其重要性
  9. jq获取页面url后边带的参数
  10. java c c++ 1000 套计算机毕业设计(论文+源码)
  11. git切换远程分支并拉取最新代码
  12. oracle peoplesoft enterprise,Solix实现与Oracle PeopleSoft Enterprise9.1整合
  13. PostgreSQL 13新特性:fetch first with ties
  14. centos7.4运行hyperLedger fabric 1.3.0 first network
  15. 按照拼音对数组中的中文字符串排序的算法
  16. Jupyter notebook如何更换主题、更改字体大小?
  17. Filter为什么会在一次请求执行多次doFilter?
  18. 拜占庭将军问题与PBFT算法和POW共识
  19. WiFi碰碰贴开发方案
  20. macOS 使用 QuickLook 预览高亮查看任意代码源文件

热门文章

  1. 前端学习(3269):js中this在类中的表现
  2. 前端学习(3238):react生命周期4
  3. 前端学习(3224):字符串形式
  4. 工作234:按钮禁用
  5. 前端学习(2659):组件间传参
  6. 前端学习(2598):按钮控制操作
  7. “约见”面试官系列之常见面试题之第九十三篇之vue获取数据在哪个周期函数(建议收藏)
  8. “约见”面试官系列之常见面试题之第五十九篇之js中push(),pop(),unshift(),shift()的用法小结 (建议收藏)
  9. 前端学习(1918)vue之电商管理系统电商系统之渲染权限列表的数据
  10. 前端学习(1906)vue之电商管理系统电商系统之渲染修改用户的表单