软件工程课堂练习——N层电梯只停一层求乘客爬楼层数最少(基本方法+优化方法)

题目:

•石家庄铁道大学基础大楼一共有四部电梯,每层都有人上下,电梯在每层都停。信1201-1班的张一东觉得在每层都停觉得不耐烦。

•由于楼层不太高,在上下课高峰期时时,电梯从一层上行,但只允许停在某一楼层。在一楼时,每个乘客选择自己的目的层,电梯则自动计算出应停的楼层。

•问电梯停在那一楼层,能够保证这次乘坐电梯的所有乘客爬楼梯的层数之和最少。

一、设计思想

1、解法一

  可以从第一层开始枚举一直到第N层,然后计算如果电梯在第x层停的话所有乘客总共要爬多少层楼。这是最为直接的一个解法。程序代码就是两重循环,找到最小值,这个算法的时间复杂度O(N^2)。

2、解法二(优化)

  假设电梯停在第 i 层楼,我们计算出所有乘客总共爬楼梯的层数是Y。如果有N1个乘客想去的楼层在第 i 层之下,有N2个乘客正好想去的楼层是第 i 层,有N3个乘客想去的楼层在第 i 层之上。这个时候,重点来了:如果电梯改停在i-1层,所有目的地在第i - 1层以下的乘客可以少爬1层,总共少爬N1层,所有在i层及以上的乘客要多爬一层,总共多爬N2+N3层,这时总共需要爬Y-N1+N2+N3。反之,如果电梯在i+1层停所有目的地在第 i 层以上的乘客可以少爬1层,总共少爬N3层,所有在 i 层及以下的乘客要多爬一层,总共多N1+N2层,这时总共需要爬Y+N1+N2-N3层。可见,当N1 > N2+N3 时,电梯在第i-1层楼停更好;当N1+N2 <  N3 时,电梯在i+1层停更好。其他情况在第i层更好。如此一来,问题的解法就出来了,从第一层开始考察,计算各位乘客走的楼层的数目,然后根据N1,N2,N3之间的关系进行调整,知道找到最佳楼层,这样算法时间复杂度优化到了O(N)。

二、源代码

 1 package com.java.lianxi;
 2
 3 import java.util.Scanner;
 4
 5 public class lianxi6 {
 6     public static void main(String[] args){
 7         int N,num;//电梯层数,乘客要停的电梯数
 8         Scanner in=new Scanner(System.in);
 9         System.out.print("请输入楼层数:");
10         N=in.nextInt();
11         int array[]=new int[N+1];
12         for(int i=2;i<=N;i++)
13         {
14             System.out.print("请输入去第"+i+"层的乘客数:");
15             array[i]=in.nextInt();
16         }
17         fangfa1(N,array);
18         fangfa2(N,array);
19     }
20     public static void fangfa1(int N,int array[])//枚举
21     {
22         int sum[]=new int[N+1];//停在某层的结果
23         for(int i=2;i<=N;i++)sum[i]=0;
24         for(int i=2;i<=N;i++)
25         {
26             for(int j=2;j<=N;j++)
27             {
28                 int k=i>j?(i-j):(j-i);
29                 sum[i]+=array[j]*k;
30             }
31         }
32         int min=sum[2],m=2;
33         for(int i=3;i<=N;i++)
34         {
35             if(sum[i]<min)
36             {
37                min=sum[i];
38                m=i;
39             }
40         }
41         System.out.println("使用方法1得到的结果是:停在第"+m+"层,上下楼层数最小值"+min);
42
43     }
44     public static void fangfa2(int N,int array[])//优化
45     {
46         int N1=0,N2=0,N3=0,i,j,k;
47         int min=0,m=2,sum=0;
48         array[1]=0;
49         for(i=2;i<=N;i++)
50             sum+=array[i];
51         for(i=2;i<=N;)
52         {
53             N1+=array[i-1];
54             N2=array[i];
55             N3=sum-N1-N2;
56             if(N1+N2<N3)
57                 i++;
58             else
59                 break;
60         }
61         for(j=2;j<=N;j++)
62         {
63             k=i>j?(i-j):(j-i);
64             min+=array[j]*k;
65         }
66         System.out.println("使用方法2得到的结果是:停在第"+i+"层,上下楼层数最小值"+min);
67     }
68
69 }

三、运行结果截图

四、心得体会

  通过这次练习,我懂得了拿到一道题,首先要先想用最简单最直接的方法来实现,然后再想办法优化,提高算法效率。

时间: 2024-10-24 06:57:06

软件工程课堂练习——N层电梯只停一层求乘客爬楼层数最少(基本方法+优化方法)的相关文章

N层电梯只停一层情况下,求所有人爬楼层数最少

一,题目: 石家庄铁道大学基础教学楼一共有四部电梯,每层都有人上下,电梯在每一层都停.信1201-1班张一东每层都停有点儿不耐烦.如果在上下课高峰时刻电梯从一层上行,但只允许停留在某一层.每个人选择自己的目的地,使他们爬楼层数最少. 二,设计思想: 1,(基础算法)首先用最笨的办法去思考这个问题,就是让电梯从第二层楼开始停.然后计算所有人爬楼层数之和,知道第N层,然后找出爬楼层数最少的就是电梯要停留的层数. 2,(优化算法)假设电梯停在第 i 层楼,我们计算出所有乘客总共爬楼梯的层数是Y.如果有

软件工程课堂作业04

软件工程课堂作业04 源代码: 1 package jian; 2 import java.io.*; 3 import java.util.Scanner; 4 public class Point3D{ 5 public static int Lenght(int list[],int lenght) 6 { 7 int i,max; 8 max=list[0]; 9 for(i=1;i<=(lenght-1);i++) 10 { 11 if(list[i]>max) 12 { 13 ma

结对合作-乘坐电梯的所有乘客爬楼梯的层数之和最少

组员 石鹤李海超 一.题目 石家庄铁道大学基础大楼一共有四部电梯,每层都有人上下,电梯在每层都停.信1201-1班的张一东觉得在每层都停觉得不耐烦. 由于楼层不太高,在上下课高峰期时时,电梯从一层上行,但只允许停在某一楼层.在一楼时,每个乘客选择自己的目的层,电梯则自动计算出应停的楼层. 问电梯停在那一楼层,能够保证这次乘坐电梯的所有乘客爬楼梯的层数之和最少. 二.设计思想 算出停在各层需要爬的层数,比较得出最小的. 我也考虑了老师说的优化方法,但我觉得假如2层和4层都满足那种条件,而那个公式没

软件工程课堂作业(十三)——电梯调度

一.题目: 石家庄铁道大学基础大楼高18层,共有四部电梯.在上下课高峰期时,电梯从一楼上行,但只允许停在某一楼层.在一楼时,每个乘客选择自己的目的层,电梯则自动计算出应停的楼层.设计算法算出电梯停在哪一楼层能够保证这次乘坐电梯的所有人爬楼梯的层数之和最少. 二.设计思路: 输入楼层有一个for循环,便利最小楼层数时需要嵌套for循环. 获取所有乘客要爬的楼层数方法如下:从2楼一直便利到18楼,每一层都计算出所有乘客要爬的楼层数.乘客要去的的楼层和当前停的楼层数之差绝对值就是该乘客要爬的楼层数,每

软件工程课堂作业(七)续——电梯调度之整体设计

一.题目要求: 1.可以获得电梯和乘客所在楼层: 2.可以根据乘客的需求到达想到达的楼层. 二.设计思路: 1.通过用户输入可以获取乘客和电梯所在楼层: 2.通过循环,输出电梯向上/向下走的过程. 三.源代码: 1 // 电梯调度——胡亚宝 2 // 3 4 #include "stdafx.h" 5 #include<iostream> 6 using namespace std; 7 8 9 int _tmain() 10 { 11 int a,b,c,m,i; 12

课堂练习之乘坐电梯的方法

一.设计思路 对这个问题进行思考的过程中,还是选择了最原始的方法,需要上电梯的人,没人都按下自己要前往的目的楼层,然后假设一个最优的目的楼层, 用每个人按下的目的楼层减去假设的最优楼层,取绝对值然后再相加,所得的和就是全部人需要爬的楼层数,然后选择最小的值,返回它的脚标,就是最优的目的楼层数. 二.源代码 1 import java.util.*; 2 3 class Elevator 4 { 5 public static int min(int s[]) 6 { 7 int min = s[

软件工程——课堂改进意见

这学期有一门必修课程<软件工程>.老师是软件工程专业的系主任王建民老师.从上第一节<软件工程>课起.就发现了王老师讲课特点:1)上课不准睡觉,抓到睡觉的同学会提出批评.2)上课不准玩手机3)上课带电脑,会有相应的课堂练习4)讲课激情洋溢,上课氛围从不会沉闷.感觉课堂练习还是蛮重要的,像我们之前听的课或现在正在进行的课程,全都是老师在讲台上讲,同学们在下面死气沉沉的听,一节课下来几乎不动手,不动脑,就只是机械的抬头看黑板,看多媒体.由于大一的C++基础比较薄弱,加上学完这门课程后好久

软件工程课堂训练——结对开发之环状二维数组

一.题目及要求: 题目:返回一个整数数组中最大子数组的和 要求(新加):①输入一个二维整形数组,数组里有正数也有负数:②二维数组首尾相接,像一条首尾相接的带子一样. 结对人员:胡亚宝  焦燕 二.设计思路: 这个题目其实就是二维数组和环型数组的结合,要解决这个问题,将之前的两个问题融合一下即可. 首先解决求出二维数组中最大子数组的问题,然后沿用一维数组的方法,将第一列放到最后一列,在求出新的二维数组的最大子数组,依次求出各个二维数组的最大子数组. 三.部分源代码: 1 for (m=0;m<5;

软件工程课堂作业(四)——结对开发

一.题目及要求: 1.题目:返回一个整数数组中最大子数组的和. 2.要求: ①输入一个整形数组,数组里有正数也有负数:数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和:求所有子数组的和的最大值:要求时间复杂度为O(n). ②两人结对完成编程任务:一人主要负责程序分析,代码编程,一人负责代码复审和代码测试计划. 3.结对人员:胡亚宝 焦燕 二.设计思路: ①第一个方法,定义一个数组,将所有的子数组的和都求出来放到该数组中,再求最大值,输出.但是在编写过程中,我们发现如果用循环方式存放