Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4253483
  • 博文数量: 82
  • 博客积分: 671
  • 博客等级: 上尉
  • 技术积分: 24576
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-18 16:08
个人简介

www.kernel.org

文章分类

全部博文(82)

文章存档

2016年(1)

2015年(3)

2014年(12)

2013年(14)

2012年(52)

分类: C/C++

2013-04-18 23:37:02

    最近发现自己好久没有研究过算法了,达尔文坚持进化论,而拉马克则提出“用尽废退”理论。在学术领域我还是比较赞同拉马克的观点。程序设计道理也是一样的,只有多看优秀的代码的,学习优雅的设计框架和思想,经过充分的思考并将其移花接木般应用在自己的程序里才是学习的本质。以前我们的高中老师管这个技能叫做“能力迁移”。
   曾经在哪儿看到过一道面试还是笔试题,具体及不太清楚了,当时没多想。这几天它突然从我脑子中迸了出来,就把它拿来给大家打打牙祭吧。具体是这样的:
   如下图所示,从下午15:00开始到晚上21:00整,时针和分钟一共重合了多少次?并给出它们相遇的时刻。

    第一问简单,肯定是6次这没什么可说的。关键是第二问,求出它们相遇的时刻。确切的说,这道题考查的是程序设计的童子功:数学分析和运算能力。因为我们知道计算机和数学是不分家的,很多问题看似很复杂,其实本质上还不就那么点事儿。就像以前高考时,每次模拟考试,我们班主任总是不忘记叮嘱大家,一定要站在命题人的角度出发,想想他想考你们什么,然后才能得心应手,他管这个过程叫“破题能力”。OK,又扯远了。既然这道题目出现在程序员面试课堂里,那我们就来探究一下它究竟想考什么。

    表盘共360度,一共分成60个刻度,所以每个刻度是6度,分针每转360度是1小时,时针才转30度。如下:

    假如说,时针和分针起始时所成夹角为c度(本题中c=90),时针和分针相遇时他们各自分别走过了x度和y度,我们可以很容易的得出一个二元一次方程组:

   解这个方程组,其实也是相当easy的,初中二年级水平就可以应付了。其中x=8.18,y=98.18。因为时针每走6度是10分钟,也就是说分针是在15:10分~15:20之间与时针重合的。为了计算粒度更精确一点,分针每1分钟会走过6度,所以相遇时分针共走了98.18/6=16.36分钟,取整之后就是16分。最后我们可以得到该问题的一般性结论:
   最后,该方程的解如表所下(单位:度):

c

90

120

150

180

210

240

x

8.18

10.91

13.64

16.37

19.09

21.82

y

98.18

130.91

163.64

196.37

229.09

261.82

具体时刻

15:16

16:21

17:27

18:32

19:38

20:43


   如果这道题继续问:当时针和分针相遇时,秒针能和它们相遇吗?如果能请说明原因,如果不能请给出此时秒针所指的时刻。既然原理都搞清楚了,那么再精确一点又何妨呢?不就多个条件而已嘛。同样的,秒针每转360度是1分钟,分针才转过6度,假如说重合的时刻秒针走过的度数为z,我们可以得到一个三元一次方程组:
    倘若一直用初中二年级的水平来解答,显得太没面子了,好歹咱也是学过线性代数的人,不能把大学功课全还给老师了。幸好我还记得一点:
    上述方程可以整理如下:
    不管你用高斯消元法还是其他,因为行列式里0比较多,所以我决定用克莱姆法则求解,最后,解向量的形式如下所示:

    其中:

    z求出来的结果最终要对360求余,结果如下表所示(单位:度):

c

90

120

150

180

210

240

x=c/11

8.18

10.91

13.64

16.36

19.09

21.82

y=12c/11

98.18

130.91

163.64

196.36

229.09

261.82

z=720c/11

129.6

294.5

100.8

259.2

64.8

230.4

具体时刻

15:16:21

16:21:49

17:27:16

18:32:43

19:38:10

20:43:38

    当我想对这个结果进行验证时,被windows自带的时针着实给坑了一把。正常情况下,应该是秒针每走60度,分针就走1度;分针每走12度,时针就走1度。可它偏偏没这么设计,网上苦苦搜寻无果之后,哥们打算自己严格按照“国际标准”来自己写个带表盘的时钟,代码有些烂,不敢保证完全没有BUG,呵呵。感兴趣的童鞋可以从clock.zip下载源代码,我用qt写的。最后的验证结果如下:

 

    另外,如果这个题初始条件改成从中午12点到凌晨12点,上述公式里我们只要修改c的值就可以了,从0到360,步长是30,剩下的就是算术基本功的考查了。说白了这道题考查的知识点太基础了,就是看你细心不细心。如果是面试或笔试题,由于临场环境,就在大家都找到方法的前提,考的就是你的细心认真程度。
  最后,我承认自己是个马大哈子,哈哈…


阅读(6667) | 评论(3) | 转发(3) |
给主人留下些什么吧!~~

laifu_lian2015-05-29 09:56:14

15点到21点时分秒不能重合,因为你忽视了初始条件y = z + 360*k(k = 1\\2\\3...)

wjlkoorey2582013-05-11 21:24:03

Bean_lee:反感一切面试题目。
哥是不是有点极端啊。

我觉得要是让你面试别人可能心里会舒坦点

回复 | 举报

Bean_lee2013-04-29 08:58:10

反感一切面试题目。
哥是不是有点极端啊。