`
Eastsun
  • 浏览: 309482 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

程序员2007年3月刊上的一道算法题

阅读更多

       晚上无聊的时候把以前的<程序员>杂志拿出来see see,于是就看到了这个算法题.这文章之前也看过,但当时稍微想了一下就溜过去了.今天看的时候突然产生了一些疑问,于是动手写了几行代码测试了下,结果发现文章中的说法并不完全対.

      哦,讲了这么久,忘了说这个题在杂志的第65页的第二题.

     注意: 原文并没有给出最优策略 的定义,我这儿根据原文的意思考虑的是这样一种策略:

                  给出一种策略,使得在最坏的情况下,测试的次数最少

      下面是我写的代码:(动态规划算法,时间复杂度O(N^2))

java 代码
  1. /**  
  2.  原题: 有一个100层高的大厦,你手中有两个相同的玻璃围棋子。从这个大厦的某一层扔下围棋子就会碎,用你手中的这两个玻璃围棋子,找出一个最优的策略,来得知那个临界层面。  
  3.  算法(递归):  
  4.      记为n层楼时最少要测试的次数为f(n),则:  
  5.      1. f(1) =0;  
  6.      2. 考虑n+1时,若第一个棋子从第k层扔下,此时分两种情况  
  7.          a. 碎了. 则临界值不大于k,由于只剩一颗棋,只能从第1层开始往上测试,最多需再测试k-1次(此种情形共测试了k次)  
  8.          b. 没碎. 则临界值在k之上,此时还剩2颗棋,可归结到f(n+1-k)的情形(此种情况共测试了1+f(n+1-k)次)  
  9.        f(n+1) = min{ max{k,1+f(n+1-k)}: 1<=k<=n+1}  
  10.  @author Eastsun  
  11.  @version 1.0 2007/5/5  
  12. */   
  13. import  java.util.*;   
  14. public   class  Best{   
  15.      private   static  Map map = new  HashMap();   
  16.      //求n层楼时最少用的次数   
  17.      public   static   int  min( int  n){   
  18.          if (n< 0 throw   new  IllegalArgumentException();   
  19.          if (n<= 1 return   0 ;               //n<=1时,为了方便起见,这里记min(0) =0   
  20.         Integer s =map.get(n);   
  21.          if (s!= null return  s;   
  22.          int  min =n;                      //一个上界(这是i取n次的情形): n   
  23.          for ( int  i= 1 ;i
  24.              int  t1 = 1  + min(n-i);        //没碎,递归求解   
  25.              int  t2 =t1>i?t1:i;           //两种情况的最坏情形   
  26.              if (min>t2) min =t2;   
  27.         }   
  28.         map.put(n,min);   
  29.          return  min;   
  30.     }   
  31.      private   static  List list = new  LinkedList();   //用于保存求解路径   
  32.      /**  
  33.       打印出测试路径  
  34.     */   
  35.      public   static   void  solve( int  n){   
  36.          if (n< 0 throw   new  IllegalArgumentException();   
  37.          if (n<= 1 ){   
  38.             ListIterator iter =list.listIterator();   
  39.              if (!iter.hasNext())  return ;   
  40.             System.out.print(iter.next());   
  41.              while (iter.hasNext()) System.out.print( " -> " +iter.next());   
  42.             System.out.println();   
  43.              return ;   
  44.         }   
  45.          int  min =min(n);   
  46.          for ( int  i= 1 ;i<=n;i++){   
  47.              int  t1 = 1 +min(n-i);   
  48.              int  t2 =i>t1?i:t1;   
  49.              if (t2==min){   
  50.                 list.add(i);   
  51.                 solve(n-i);   
  52.                 list.remove(list.size()- 1 );   
  53.             }   
  54.         }   
  55.     }   
  56.      public   static   void  main(String[] args){   
  57.         System.out.println( "Min :" +min( 100 ));    //注意:有很多组结果   
  58.         solve( 100 );   
  59.     }   
  60. }  

运行程序可以看出,对于n=100的情形,存在很多种最优策略,第一次测试选择的楼层可以是从8到14的任意一层.

 

ps:贴上去的代码有点走样,请下载附件

  • Best.rar (1.2 KB)
  • 描述: 本文中的源代码
  • 下载次数: 97
分享到:
评论
35 楼 longrm 2007-06-14  
caocao 写道
要是面试题,面试官嘿嘿冷笑到,玻璃围棋子3-4楼砸下来就已经挂了,这是常识,所以两次就够了。那就郁闷了 

哈哈,这个答案最好的啦,任何事情还是得联系实际滴,其实用数学方法可以很快的算出来啊,编个程序的时间够偶踢一场足球啦
34 楼 huangpengxiao 2007-05-21  
多来点算法帖 这方面需要恶补
33 楼 xxxcccvvv 2007-05-20  
coolwangyu 写道
我觉得这个是一个典型的概率计算。


我觉得也是
32 楼 caocao 2007-05-13  
Eastsun 写道
楼上牛,3楼怎么一次测出来?洗耳恭听~


是啊,同问,俺一向就是不懂装懂,哈哈
31 楼 blu3leaf 2007-05-12  
嗯嗯~~楼主的思想简单的来说就是一颗找大范围,剩下一颗找精确的楼层
找大范围的可以一次走10层,20层,然后从最后一次不碎的地方开始用剩下的那颗遍历。
30 楼 Eastsun 2007-05-11  
楼上牛,3楼怎么一次测出来?洗耳恭听~
29 楼 ahau205109 2007-05-11  
算法明显错误:
   按你那么算: 3楼高的 也要测试2次?
   最多 1次就够了吧       


不懂不要装懂
28 楼 eboge 2007-05-11  
开始没有仔细看楼主的说明, 只是感觉说的有点麻烦, 好像复杂化了, 原来是我没有注意到,楼主是得出很多的不同策略来实现最优解。这样是很好, 不过如果只是想解决问题, 直接求k!=n中的最接近的k值好像很方便,不用那么麻烦咯, ^_^
27 楼 Eastsun 2007-05-11  
.........
楼上没看我写的代码把?
代码打印出来的是最优策略,最优解(最小测试次数)只有一个,但达到这个解的策略不止一个.
26 楼 eboge 2007-05-11  
我说的就是既然14!已经是最优的解了, 楼主怎么会来那么多的最优解?对于每一层楼来说概率都是相同的啊
25 楼 caocao 2007-05-11  
要是面试题,面试官嘿嘿冷笑到,玻璃围棋子3-4楼砸下来就已经挂了,这是常识,所以两次就够了。那就郁闷了 
24 楼 Eastsun 2007-05-11  
皑皑...
楼上大概没用过JDK1.5了.
23 楼 johnderlin 2007-05-11  
map.get, 不是要object 做para 吗?怎么给了个int?

还有, if(s!=null) return s; 这个方法不是要求返回int?

22 楼 a_nuo 2007-05-10  
先拿来研究一下
21 楼 jesse 2007-05-09  
error
20 楼 bonny 2007-05-09  
14!等于14+13.。。。+1
每次步长+1是为了抵消上一次投掷浪费的那一次
是为了求得答案的稳定性

100%n+n-2在步长一致的情况下,答案是18-10的区间
利用步长可以把答案稳定在14附近

明白了么?
19 楼 eboge 2007-05-09  
我看了一段时间, 发现这个问题可以这样说: 因为对于每一层楼来说,是临界点的几率都一样,所以,开始选择的k,应该尽量保证k+(k-1)+…+1=n,这样不管临界点在哪里,最多次数就是k。
而对于n=100时, k约等于14。和楼主的答案不谋而合,但是楼主答案的后半部的意图我不是很了解。
18 楼 hexstar 2007-05-09  
刚好在手边就有这一期.
文章中好像并没有写这是一个算法,仅仅是一种推理.
就是其中的14!=105>100 这个不太明白是什么意思.
哪位大侠解释一下?
17 楼 Eastsun 2007-05-09  
bonny 写道
我那个公式的确有错误
应该是100%n+n-2

不过得到的答案是从10到18,不够稳定(考虑到平均是14)

原因是每个区间的大小都一样,我把它们的步长设为1

这样
我第一次从14楼丢(步长为13),第2次从27楼丢(步长为12)。。。。。
答案就稳定在14了


确认一下,这儿是 100%n+n-2,还是100/n+n-2?
|100%n|+n-1取最小值的n与100%n+n-2取最小值时的n有不同么?

另外,当n=9(9层楼的时候),按你的公式应该是几次?
16 楼 dovecat 2007-05-09  
哦!反正就是玩到那个棋子碎了为止是吧?

相关推荐

    程序员面试经典算法题

    《程序员面试经典算法题》是针对程序员在面试过程中可能会遇到的算法问题进行深入解析的一份资源。这份资料旨在帮助程序员提升算法思维,从而在技术面试中脱颖而出。通过学习和掌握这些经典算法,不仅可以提高编程...

    程序员的算法趣题.pdf.zip

    《程序员的算法趣题》是一本专门为IT从业者和有志于进入这个领域的学习者准备的算法书籍。它通过一系列有趣且富有挑战性的题目,旨在帮助读者深入理解和掌握计算机科学中的核心算法,提升解决实际问题的能力。这本书...

    程序员算法趣题——随书源码

    《程序员算法趣题——随书源码》是一个与算法相关的学习资源,包含了增井敏克著作《程序员算法趣题》中的实例代码。增井敏克是算法领域知名的专家,他的书籍通常深入浅出,旨在帮助程序员提升算法思维和解决实际问题...

    2007年5月程序员试题标准答案.rar

    【标题】"2007年5月程序员试题标准答案.rar"揭示了这是一份针对2007年中国软件技术资格考试(软考)程序员级别的试题及官方标准答案的资料集合。软考是中国计算机技术与软件专业技术资格(水平)考试,旨在测试考生...

    2007年上半年程序员考试下午试题及答案

    综上所述,2007年上半年程序员考试下午场试题涵盖了数据结构与算法、面向对象编程、数据库设计等多个方面的重要知识点。通过深入学习这些核心概念和技术,不仅能够帮助考生顺利通过考试,更重要的是能够提升自身的...

    程序员算法大全算法数据结构智力题

    本资源"程序员算法大全算法数据结构智力题"显然是为了帮助程序员提升在这两个关键领域的理解与技能。 算法可以看作是解决问题或执行任务的精确步骤,它们决定了计算机程序如何处理信息。在编程中,我们常常会遇到...

    程序员面试智力、算法题汇总一.pdf,这是一份不错的文件

    程序员面试智力、算法题汇总一.pdf,这是一份不错的文件

    程序员2009上半年下午试题及答案

    根据提供的标题“程序员2009上半年下午试题及答案”以及描述中的信息“程序员2009上半年下午试题及答案,解答和详细,还有其他,要的联系我”,我们可以推测这份文档包含了2009年上半年程序员资格考试下午场的试题及其...

    历年程序员考试试题(2007年5月——2008年11月)

    这些历年程序员考试试题涵盖了2007年5月至2008年11月期间的考试内容,旨在帮助备考者了解当时的考试趋势、重点及常见题型。在这段时间内,程序员考试通常会测试应试者的计算机基础知识、编程能力、算法理解、软件...

    2007年上半年 程序员 上午试卷 及 答案

    【标题】"2007年上半年 程序员 上午试卷 及 答案"涉及的是2007年全国计算机技术与软件专业技术资格(水平)考试中程序员级别的上午理论部分。这类考试通常包括计算机基础知识、编程语言、数据结构、算法分析、操作...

    程序员必备算法知识

    在IT行业中,算法是程序员解决问题的关键工具,它们是编程的基础,能够帮助我们高效地处理数据和执行任务。本文档集合中的四个PHP文档深入探讨了程序员应掌握的一些经典算法,这对于提升编程技能至关重要。 首先,...

    程序员电子刊2007年2月

    《程序员电子刊》2007年2月刊是一本专注于IT技术和行业的专业杂志,它为当时的程序员和科技爱好者提供了丰富的技术资讯、行业动态以及深度分析。这份刊物在那个年代对于推动中国IT行业发展起到了积极的作用,是许多...

    Java算法集题大全.zip

    Java算法集题大全Java算法集题大全Java算法集题大全Java算法集题大全Java算法集题大全Java算法集题大全Java算法集题大全Java算法集题大全Java算法集题大全Java算法集题大全Java算法集题大全Java算法集题大全Java算法...

    程序员笔试常考算法题

    程序员笔试常考算法题 嵌入式程序员,C程序员,JAVA程序员值得参考

    程序员算法趣题 原文

    本书是一本解谜式的趣味算法书,从实际应用出发,通过趣味谜题的解谜过程, 引导读者在愉悦中提升思维能力、掌握算法精髓。此外,本书作者在谜题解答上,通 过算法的关键原理讲解,从思维细节入手,发掘启发性算法新...

    程序员实用算法.zip

    在IT行业中,算法是程序员的核心技能之一,它们是解决问题和设计高效程序的基础。"程序员实用算法.zip"这个压缩包很可能包含了一系列与编程相关的算法实现、解释或案例,旨在帮助程序员提升这方面的能力。以下是对...

    程序员算法题源代码

    "程序员算法题源代码"这个压缩包文件很可能包含了众多经典的算法实现,旨在帮助程序员巩固和提高算法水平。 一、排序算法 排序算法是计算机科学中最基础且广泛使用的算法之一,包括冒泡排序、插入排序、选择排序、...

    2007年上半年程序员试题及标准答案

    2007年上半年程序员考试是针对计算机编程技术的一次专业评估,旨在测试考生对编程基础知识、算法理解、数据结构掌握、软件工程实践以及问题解决能力等多方面的技能。这次考试的试题与标准答案提供了宝贵的复习资源,...

    程序员\程序员上午题目\2007年上半年程序员考试上午试题.doc

    标题和描述提及的是"2007年上半年程序员考试上午试题",这显然指的是中国计算机技术职业资格认证中的一项考试,通常包括了计算机编程、软件工程、数据结构、算法分析等多个IT领域的知识。这个考试是评估程序员基础...

Global site tag (gtag.js) - Google Analytics