投递问题

Time Limit: 1 Sec  Memory Limit: 64 MB
Submit: 0  Solved: 0
[Submit][Status][Discuss]

Description

有一座10层高的建筑物,搬运工小李需要搬运一些相同的包裹来往于各楼层之间。小李可以不搬运任何包裹而上楼下楼,也可以在搬运某一包裹的途中停下来,将该包裹放在他所处的楼层,然后去做其他的事情。小李从一层开始工作,并且工作结束后他必须返回一层。 现在请你编写一个程序,求出小李完成工作所需的最少上楼层数m(下楼层数不计),并且输出其搬运路径。

Input

输入数据的第一行有一个正整数k(0 < k< =50),表示搬运工所需搬运的包裹数。 接下来有k行,每行有两个整数(整数之间用一个空格分开)。第s(2< =s< =k+1)行的两个整数i,j(1< =i,j<= 10),表示s-1号包裹需要从第i层搬运到第j层。

Output

输出数据的第一行是一个整数m,表示搬运工完成工作所需的最少上楼层数。 接下来输出搬运工的搬运路径,每行有3个整数x,y,z(每两个整数之间用一个空格分开)。x表示搬运z号包裹的出发楼层;y表示搬运z号包裹的终止楼层;z表示被搬运包裹的编号,若z为0,则表示搬运工没有搬运任何包裹而上楼下楼。

Sample Input

2
2 5
8 10

Sample Output

9
1 2 0
2 3 1
3 4 1
4 5 1
5 6 0
6 7 0
7 8 0
8 9 2
9 10 2
10 9 0
9 8 0
8 7 0
7 6 0
6 5 0
5 4 0
4 3 0
3 2 0
2 1 0

HINT

Source

题目分析:

本题是一个关于包裹投递的问题。题目给出一些包裹的投递要求,需要搬运工小李在一个10层高的建筑物中完成这些包裹的投递任务,要求找出一个最优的搬运方案,使得搬运工小李完成全部工作任务而所上楼的层数最少。从题目所给出的条件来看,搬运货物的路径不是很长,即建筑物的高度只有10层;但是需要搬运的包裹却比较多,最多会有50个包裹,故整个问题的搜索量会很大,搜索算法的时间复杂度很高,不是一个有效的算法。仔细分析题目中的条件,我们可以将问题转化为一个图,从而运用关于图的算法来解决这个问题。

题目只要求找到上楼层数最少的方案,并没有对上楼方案有其他限制,而且在处理某一个包裹的投递任务时,可以在中途暂停这一任务,而去处理其他的包裹投递任务,这样我们就可以把一个包裹的投递任务(上n层楼或下n层楼)分成若干个简单的投递路线(只上一层楼或者只下一层楼)。如此我们就可以把问题用一个图来表示出来,图的顶点表示楼层,图的边表示投递路线。由于每上一层楼;每下一层楼,也必然要先上一层楼,所以图中的边是具有对应关系的。构造出这个图之后,问题就变得十分简单了,很容易就可以求出上楼的最少楼层数和最优的投递方案。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 11
int floors=10;//总的楼层数
int uptable[N],downtable[N],Eup[N],Edown[N];//存储转化问题后的图
int k,i,m;
int floor;
int package[51][3];//存储包裹的投递任务
void createtable()//构造问题转化为图
{
int i,j;
memset(uptable,0,sizeof(uptable));//初始化数组
memset(downtable,0,sizeof(downtable));
for(i=1; i<=k; i++)
{
if(package[i][1]==package[i][2])continue;//第i层没任务
if(package[i][1]<package[i][2])//有任务,是要上楼的,统计uptable的次数
{
for(j=package[i][1]; j<package[i][2]; j++)
{
uptable[j]++;//统计
}
}
else
{
for(j=package[i][2]; j>package[i][1]; j--)
{
downtable[j]++;//如果是要下楼,统计downtable的次数
}
}
}
for(i=1; i<=floors; i++)//存储,待用
{
Eup[i]=uptable[i];
Edown[i]=downtable[i];
}
for(i=1; i<=floors; i++)//下楼和上楼的次数需要相同,因此uptable[i]和downtable[i]都需要取可能的最大值
{
if(uptable[i]>downtable[i])
{
downtable[i]=uptable[i];
}
else
{
uptable[i]=downtable[i];
}
}
for(i=floors-1; i>=1; i--)//检查有没有楼层是不需要搬货物而走上去的
{
if(uptable[i]==0&&uptable[i+1]!=0)//有
{
uptable[i]=1;
downtable[i]=1;
}
}
m=0;
for(i=1; i<=floors; i++)//统计一共要往上走的总层数
{
m+=uptable[i];
}
printf("%d\n",m);//输出
return ;
}
void output(int x,int y,int z)//输出一步
{
printf("%d %d %d\n",x,y,z);
}
int upstair(int f)//上一层楼
{
int i,bb;
int p;
floor=f;
if(uptable[floor]==0)return 0;//判断能否上楼
bb=1;
p=0;
for(i=1; i<=k; i++)//检查所有在floor层的需要往上搬的货物,找出目标地所在层次最高的货物,记住货物p
{
if(package[i][1]==floor&&(package[i][1]<package[i][2]))
{
if(p==0)p=i;
else if(package[p][2]<package[i][2])p=i;
bb=0;
}
}
if(bb==1)//如果floor层没有需要往上搬的货物,则看floor层上面还有没有货物来决定需不需要往上走
{
if(Eup[floor]==uptable[floor]) return 0;
else
{
output(floor,floor+1,0);//不搬货物往上走一层
}
}
else
{
package[p][1]++;//货物被搬上了一层,更新其所在层数
output(floor,floor+1,p);//搬货物p往上走一层
Eup[floor]=Eup[floor]-1;
}
uptable[floor]=uptable[floor]-1;//需要往上走的层数减1
floor++;//层数加1
return 1;//返回成功往上走一层
}
int downstair(int f)//下一层楼
{
int i,bb,p;
floor=f;
if(floor==1)return 0;
if(downtable[floor-1]==0)return 0;//判断是否能下楼
bb=1;
p=0;
for(i=1; i<=k; i++)//检查所有在floor层的需要往下搬的货物,找出目标地所在层次最低的货物,即为货物p
{
if(package[i][1]==floor&&(package[i][1]>package[i][2]))
{
bb=0;
if(p==0)p=i;
else if(package[i][2]>package[i][1])p=i;
}
}
if(bb==1)//如果floor层没有需要往下搬的货物,则看floor层下面还有没有货物来决定需不需要往下走
{
if(Edown[floor-1]==downtable[floor-1])return 0;
else
{
output(floor,floor-1,0);
}
}
else
{
Edown[floor-1]--;
package[p][1]--;//货物被搬下了一层,更新其所在层数
output(floor,floor-1,p);//搬货物p往下走一层
}
downtable[floor-1]=downtable[floor-1]-1;//需要往下走的层数减1
floor--;//所在层减1,到了下一层
return 1;//返回
}
int main()
{
int i;
scanf("%d",&k);
for(i=1; i<=k; i++)
{
scanf("%d%d",&package[i][1],&package[i][2]);
}
createtable();//构造图
floor=1;//从第1层开始
while(1)
{
if(upstair(floor)==0)//上楼
if(downstair(floor)==0)//下楼
{
if(floor!=1)
{
printf("Error!\n");
}
else break;
}
}
return 0;
}

投递问题--图论--ACM算法相关推荐

  1. 繁凡的ACM算法全家桶(全新的模板整合计划)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的模板整合计划 ACM算法全家桶的所有内容的 Portable Document Format 版本全部 开 源 啦 !可 ...

  2. 如何出(改编)一道ACM算法题?

    本文背景 本人算法能力一般,但是为省赛和区域赛网络赛出过几道题,总结了一些自己的经验,希望与大家分享.本文不涉及具体的算法题,都是一些理论性的想法和一些建议. 题源 如果你能在没有题源的情况下自己想出 ...

  3. 图论相关算法理解和总结

    晚上学习了一些图论相关算法: 单源最短路径算法: Bellman-Ford 算法: Bellman-Ford 算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shor ...

  4. 【C语言、C++基础编程题】【基础类题集】【平顶山学院ACM算法攻关部】

    题源:平顶山学院ACM算法攻关部 目录 前言 1000:A+B Problem 1001:编写一个程序,输出指定信息 1002:求三个数最大值 1003:字符串加密 1004:计算圆柱体的面积体积等 ...

  5. 图论2-SAT算法详解

    图论2-SAT算法详解 今天我们来介绍一个我个人认为最难的算法,这是为什么呢?肯定会有许多dalao说,不就一个2-SAT,我两分钟就A掉了.然而2-SAT的细节非常的多,稍不注意就会写错,而且测试困 ...

  6. ACM算法竞赛及OJ题面常用英文单词整理

    文章目录 A B C D E F G H I J K L M N O P Q R S T U V W A abbreviation [数学] 约分; activity on edge AOE网 act ...

  7. ACM算法之基础算法

    ACM算法基础篇 基础算法有:枚举,递推,贪心,,分治,递归,构造,模拟,排序和检索 1.枚举:也叫穷举,是从问题所有可能解中一一枚举个元素,用题目给的检验条件判定哪些是无用的,那些是有用的,符合的解 ...

  8. acm算法有用吗?写给自己。

    acm算法有用吗?写给自己,也希望能帮助那些大一迷茫的人. 我是一个普通二本院校即将进入大三的acmer,一般问这个问题的人都是一个acmer的失败者,因为成功的人都去忙着学习该学习的算法了,不会问这 ...

  9. ACM算法训练【逆序对的数量】

    ACM算法训练[逆序对的数量] 题目说明 数据范围 样例 分析与代码 题目说明 数据范围 样例 分析与代码 ①归并排序基本思想: ②在归并的过程中,逆序对出现的三种情况: a.全部出现在左边的区间 b ...

最新文章

  1. Facebook人工智能实验室提出「全景分割」,实现实例分割和语义分割的统一
  2. 使用Docker Compose部署基于Sentinel的高可用Redis集群
  3. c语言课设学生管理程序,c语言程序课程设计学生成绩管理程序.doc
  4. QT的QHttpMultiPart类的使用
  5. Android代码混淆方法,Android 代码混淆零基础入门
  6. 如何使用和自定义Win11快速设置菜单
  7. 苹果cmsv10精仿迅播影院2tu风格主题模板
  8. 无法在PC上找到,android app 创建的文件 问题.
  9. Java中foreach 的用法以及注意事项
  10. matlab 快速傅里叶变换函数(fft)编写
  11. 硬盘整数大小分区问题
  12. 《可汗学院: 统计学》学习笔记
  13. 电石炉技术的发展及电石炉尾气解决方案
  14. 寻中华文化之根 承抗战先烈之志
  15. At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger fo
  16. D4.1 About an initiating master
  17. 在贷款行业中,运营商大数据精准获客,是否真实有效呢
  18. 利用PPT的平滑变换功能以及Onekey插件做变形金刚变身的过程
  19. 洛谷B2079 求出 e 的值(阶乘)
  20. 文件系统(六)—文件系统mount过程

热门文章

  1. go: cannot determine module path for source directory D:\go\code\SipSvrProxy\src\Common (outside GOP
  2. 为什么理工类专业成绩好的人,英语总是很差?
  3. 中国房价为什么会居高不下?
  4. BigDecimal ROUND_HALF_DOWN精度问题
  5. 计算机组成原理第二章笔记---计算机进化与性能
  6. 微信开发者工具创建vue项目步骤
  7. pygame-KidsCanCode系列jumpy-part0-使用sprite
  8. 论文笔记 Dependent Gaussian Processes 相关高斯过程
  9. 系统运维-20-2-openssh和openssl
  10. Servlet3 过滤器 Filer