运煤和火柴棒



1.     这个可能是一个比较经典的智力题了,和以前的那个《赛马问题》很相似,其题目如下:

你是山西的一个煤老板,你在矿区开采了有3000吨煤需要运送到市场上去卖,从你的矿区到市场有1000公里,你手里有一列烧煤的火车,这个火车最多只能装1000吨煤,且其能耗比较大——每一公里需要耗一吨煤。请问,作为一个懂编程的煤老板的你,你会怎么运送才能运最多的煤到集市?

这道题一开始看上去好像是无解的,因为你的火车每一公里就要消耗一吨煤,而到目的地有1000公里,而火车最多只能装1000吨媒。如果你的火车可以全部装下,到目的地也会被全部烧光,一丁点也不剩。所以,很多人的第一反应都是觉得这个不太可能。

如果你一开始就觉得不太可能的话,这是很正常的。不过我不知道你还会不会继续思考下去,如果你不想思考下去了,那么我很为你担忧,因为你可能并不是一个不善于思考的人,而是一个畏难的人,还有可能是一个容易放弃的人。这对于你做好 一个需要大量思考的工作的程序员来说可能并不适合。

我一开始也觉得不可能,后来想了一想,想到一个解法可以最多运送500吨煤到市场,方法如下:(希望你先自己想一想再查看这个答案


首先想到最优解的两个特征:1,火车肯定要从起点出发3次(因为每次最多运1000);2,火车前两次回到起点要用完车上存煤(否则是浪费)。
初步方案:火车前两次都运到某点x,卸下1000-2x,然后用x煤回去,第三次到x点时,车上有1000-x,然后装上x点的煤,若3000-5x不超过1000,直接到终点,用3000-5x=1000的临界条件算得x=400,这也是火车到达终点所剩下的煤。
若3000-5x超过1000,此时与原问题类似,但初始煤变为3000-5x,路程变为1000-x,我们需要选择下一个存煤点,与x点距离y,然后在y点回头一次。
然后想到第三个特征:3,火车回程要尽可能短。使火车回头的原因是火车容量为1000,理想状况为火车每次出发都装满1000的煤,所以火车第三次到达x点时共有煤3000-5x=2000,求得x=200;火车第二次到达y点时站点有存煤1000-2y,火车有煤1000-y,共计2000-3y,理想状况为2000-3y=1000,y=333,火车到达终点剩下煤1000-(1000-x-y)=533。


有时候,有些面试题是很是无厘头,这不,又有一个,还记得小时候玩的的“火柴棍游戏”吗,就是移动一根火柴棍改变一个图或字的游戏。程序面试居然也可以这么玩,看看下面这个火柴棍式的程序面试题吧。

下面是一个C程序,其想要输出20个减号,不过,粗心的程序员把代码写错了,你需要把下面的代码修改正确,不过,你只能增加或是修改其中的一个字符,请你给出三种答案

[cpp]  view plain copy print ?
  1. int n = 20;   for(int i = 0; i < n; i--){     printf("-"); }  


不过,我要告诉你,以上这些答案都不对(我就知道你会偷看答案的),不过,顺着这些思路走很接近了。呵呵。

下面是正确答案——

[cpp]  view plain copy print ?
  1. //第一种解法:在for循环中给 i 加一个负号 for(int i = 0; -i < n; i--)    
[cpp]  view plain copy print ?
  1. //第二种解法:在for循环中把 i-- 变成 n-- for(int i = 0; i < n; n--)     
[cpp]  view plain copy print ?
  1. //第三种解法:把for循环中的 < 变成 + for(int i = 0; i + n; i--)  

其它相关的变种题如下:

  • 通过修改、增加一个字符,让其输出21个减号
  • 通过修改、增加一个字符,让其只输出1个减号
  • 通过修改、增加一个字符,让其不输出减号

你可能感兴趣的:(运煤和火柴棒)