2013年大众点评实习生招聘笔试题目

来源:互联网 发布:低头族数据 编辑:程序博客网 时间:2024/04/27 15:08

晚上本来是腾讯宣讲有木有,大众点评偏偏介个时候来笔试,故意找茬儿是不是!算了,笔试就笔试吧,题目奇葩有木有,有木有!O__O"…有两部分题目,第一部分是逻辑题,分言语类和数学类,是说智力题?脑筋急转弯?no !言语题堪比公务员考试(只是听说),数学题只能说小学的奥数都望尘莫及。更奇葩的是言语类的题目超长,一个题目文字都要看半天,15 道题丫,好吧,数学题也是 15 题,20分钟后收卷!等到收卷, me 言语题还有一题没有作答,数学题只做了 3 题,O__O"…。算了,算了,逻辑题还是先不说,重点的是后面的专业笔试。

专业笔试 40 分钟,3 道题,一道题还是数学题,另外两道编程题,都是先写思路,再写程序(数学题就不写程序了,写个 p 的程序丫)。题目比较少,可以先把题目列出来,然后后面一题一题分析。

笔试题目

  1. 从凌晨 0:00 到早上 6:00,秒针分针相遇多少次,分别是在哪些时间点?
  2. 寻找一个单向链表的倒数第 n 个结点,函数原型:node fun(node *head, int n);
  3. 一个 N*N 的矩阵,每一行从左到右有序,每一列从上到下有序,都是递增,写个程序,判断一个数是否在矩阵中。

简单分析

看到第一个题目,一阵窃喜,但是又有点恐慌。类似的题目以前见过,恐怕多数人都见过:“从今天的凌晨 0:00 到明天凌晨的 0:00,时针和分针相遇多少次 ”?介个,以前见过,这里换成了秒针分针,O__O"…,这不科学。应该很难短时间内给出思路并正确作答。瞥下旁边的,在做第二题,me 也去做吧。

第二题要简单些,上次网易被问过一个题,被启发过。要找倒数第 n 个? me 先找到第 n 个结点 q,然后 q 和 头节点的 p 同时后移,只要 q 为空 (NULL) 了,p 便是倒数第 n 个结点。^_^,应该三言两语就能解决了,但是,貌似要有错误检查丫,比如倒数第 n 个结点不存在?比如 head 结点为空 NULL ?(me 竟然没有考虑,O__O"…) 比如 n 为负数?(这都行吗?!!)总之,写成程序还是比较顺利的,me 把代码贴出来,虽然没有经错测试,但是应该没有太大问题:

  1. node* fun(node *head, int n)
  2. {
  3.     int i;
  4.     node *p, *q;
  5.  
  6.     i = 0;
  7.     p = q = head;
  8.  
  9.     // if(head == NULL)    return NULL;    // error, head is NULL ? shit !
  10.     while(!= NULL && i < n){
  11.         q = q->next;
  12.         ++i;
  13.     }
  14.  
  15.     if(== NULL || i != n)
  16.         return NULL;    // error: list is short, or n is negative, or head is NULL !
  17.  
  18.     while(!= NULL){
  19.         q = q->next;
  20.         p = p->next;
  21.     }
  22.  
  23.     return p;
  24. }

有几个细节要提一下。首先题目中的函数原型是:node fun(node *head, int n); 不知道有没有看出问题来?head 是不是头节点?现在假定是!返回值是 node,那么错误返回神马?如果是指针的话,还可以 NULL 一下,O__O"…好吧,me 表示直接把原型改掉了,让它返回 node*。

上面的程序其实有很多地方要提的,比如第一行被注释掉的。它是来判断 head 是否为空的,这是 me 后来加的,不过发现,即使不加这一行,后面对于 head 为 NULL 的也返回 NULL,于是就有点多余了。上面有几个点:i < n 和 i != n,u 认为可以互换吗?—— 不能!O__O"…(why ?! 因为 n 没人说就是正数!) 还有 if(q != NULL) 能不能直接写成 if(q) 这种形式呢,基本来说,应该可以,虽然没有人说 NULL 就是 0,但是历史上的传统,基本都认定 if(p) 表示 if(p != NULL),虽然后者更正规些,但是更,咋么说,丑一些,O__O"…。

第三题,其实也比较简单,如果线性搜索一遍的话,也不过 O(n^2) 的复杂度,但是其实还有更好一点的。me 在剑指 offer 上正好瞄过一眼,脑子中有个印象:每次跟右上角的数比较,相等最好;如果右上角小的话,在下面的小矩阵中找;如果右上角大的话,从左侧的小矩阵找。总之,每比较一次,至少消去一行或是一列,这样的话,在 O(n) 的时间内就能解决问题。(为嘛?行+列 = 2 N !)

  1. int search(int d[N][N]int key)
  2. {
  3.     int i1, i2, j1, j2;
  4.  
  5.     i1 = j1 = 0;
  6.     i2 = j2 = N-1;
  7.  
  8.     while(i1 < i2 && j1 < j2){
  9.         if(d[i1][j2] == key)    return 1;
  10.         if(d[i1][j2] < key) ++i1;
  11.         else --j2;
  12.     }
  13.  
  14.     return 0;
  15. }

用递归就有点多此一举了,使用 i1、i2、j1 和 j2 表示矩阵的上面的行、下面的行、左边的列和右边的列,虽然名字有点奇葩,暂时就这样吧。后来发现,其实 i2 和 j1 是不变的,也就是最底下的一行和最左边的一列。这点 me 就不多关心了。

现在单独来分析时钟的问题,maybe 很多人以前真的有点搞不清楚。

时钟相遇问题分析

不玩 shi 你不肯罢休,O__O"…先来简单的:“从今天凌晨 0:00 到明天凌晨 0:00,时针分针相遇多少次,分别是在哪些时间点?”

因为时针和分针相对来说,赶脚相遇得少一些。如果想尝试的话,可以拿出来手表,从 0:00 转转看看,实际上凌晨 0:00 到白天正午 12:00 (0:00) 正好相遇 11 次,再到凌晨 0:00,又相遇 11 次,所以是 22 次!简单滴说,现在 0:00,分针走的快,时针走得慢,等分针一圈之后,时针正好在 1 处,也就是正好 1 点!然后 1 点多那么 1 点点相遇一次,后来 2 点多 2 点点相遇一次,3 点多 3 点点相遇第 3 次,正好 11 点多 11 个一点点又相遇勒,这个时候,正好是 12:00 点,O__O"…。如果相信感觉的话,具体时间可以倒推出来,比如?

11 次相遇之后的状态和刚开始的状态是一样的,期间过了 12 个小时,那么 11 次每次都多加那么一点点,实际上正好补了 1 个小时丫(每次相遇都是 1 小时+ 1 点点)!那么,上面说的 1 点点其实就是 60/11 分钟,或是说 1/11 小时!对不对呢?对不对呢?对不对呢?必须正确!所以相遇时间就是 1 点 60/11 分钟、2 点 120/11 分钟,...,11 点 60*11/11 分钟 = 12 点。当然,也可以转换成小时,me 就不多说了。

介个,不科学丫,u 上面的计算,都是凭个赶脚算的吧,一定正确吗?好吧,现在给出数学算法:

  1. 1 圈是 12 个小时,每小时 5 小格,所以一共 60 格;分针走一圈,是一个小时,分针走 60 格,时针走 5 格,速度之比 60 : 5 = 12 : 1;
  2. 现在看大格,不看小格,因为对时针和分针来说,小格太过于精细了。设时针的速度是 1,分针的速度是 12,速度差是 11;(速度定好了,然后 1 小时 = 1 大格,格数是路程?)
  3. 从 0:00 - 12:00,是 12 个小时,时针要走 12 大格,分针呢? 12 * 12 大格! 分针比时针多走多少大格相遇一次呢?一圈! 1 圈 = 12 大格,所以相遇?
  4. (12*12 - 12) / 12 = 11 (次)
  5. 不科学丫,有木有!相遇时间怎么计算?1 大格是 1 小时!第一次相遇 (多走 12 大格)是
  6. 12/11 = 1 + 1/11,也就是 1 小时 + 1/11 小时 = 1 小时 + 60/11 分钟!(路程差 / 速度差 = 时间)
  7. 这和上面的凭感觉分析的结果?一致!

时钟相遇问题解答

现在换成 0:00 到 6:00,换成分针和秒针。分针和秒针,走的比较精细,必须看小格丫,参照上面的分析:

  1. 1 圈是 12 个小时,每小时 5 小格,所以一共 60 格;秒针走 1 圈,分针走 1 小格,因为 60 秒 = 1 分钟,速度之比是 60:1;
  2. 设分针的速度是 1,秒针的速度就是 60,速度差是 59;( 1 小格 = 1 分钟 )
  3. 从 0:00 - 6:00,是 6 个小时,分针走多少小格呢? 6*60 = 360 小格!那秒针呢? 360*60 小格! 秒针比分针多走 1 圈 = 60 分钟 = 60 小格 相遇一次,所以相遇:
  4. (360*60 - 360)/60 = 360*59/60 = 6*59 = 354 (次)
  5. 相遇时间怎么计算?实际上一小时后,秒针和分针重合在 0:00 处丫!有木有注意到?!虽然时针比较诡异,但是 me 们不用关心时针!
  6. 秒针和分针第一次相遇时,多走了一圈 = 60 小格,60/59 = 1 + 1/59,也就是 1 分钟 + 1/59 分钟相遇一次,于是...
  7. 2 + 2/59 相遇第 2 次,... 59 + 59/59 相遇第 59 次,也就是 59 次之后,大家重新归于 0:00 这个时刻处(时针实际上已经偏走了,但是分针和秒针是对的!);
  8. 从上面的时刻,实际上也可以看出来,一小时相遇 59 次,6 小时 59*6 = 354 次!
  9. 到此结束!

可惜勒,等他们说,还有五分钟就要交卷了,me 只写完第二和第三题,在这几分钟内,me 的思路其实还没有清晰,但是已经分析到 354 次勒,然后收卷,回家!O__O"…

问题结束了吗?

题目终于解答了,虽然看起来有点晕,O__O"…但是,问过秒针和分针、分针和和时针,自然而然可以问下面几个问题:

  1. 秒针和时针一圈( 12 小时)以内相遇多少次?各在神马时间点?
  2. 时针、分针和秒针,12 小时内相遇多少次?
  3. 时针和分针在任意给的一段时间内相遇多少次?不一定从 0:00 开始。O__O"…

秒针和时针的问题,有了前面的基础,应该可以很容易回答出来。速度之比 时针 : 分针 : 秒针 = 1 : 12 : 720,如果时针和分针一圈相遇 11 次,分针和秒针一圈相遇 59 次,那么时针和秒针一圈之内应该相遇 719 次!分别在 1/719、2/719、3/719、...、719/719 的刻度处,单位是神马呢?都乘以 12 小时,就是按小时计算的结果。为什么是 12 小时呢?因为时针走一圈是 12 小时!

时针、分针和秒针从 0:00 开始,到第二天正午 12:00 (0:00),赶脚中间不会再次相遇,u 肿么看?分析:三个针的相遇本来有点手足无措,不过可以看成是时针和分针相遇,并且分针和秒针相遇。如果将一圈看成一个 1 的话,时针和分针相遇 11 次,实际上是把 1 分成 11 份,在每一份处都会相遇一下,也就是 1/11、2/11、3/11、...、11/11 。分针和秒针是一圈相遇 59 次,是在 1/59、2/59、3/59、...、59/59 处。三针相遇,就是要在前者的分数中找一个等于后者的某一个分数,大眼一看,O__O"… 只有 11/11 = 59/59,也就是,只有在 0:00 处会相遇,其他处,总是会错开。

第三个问题,可能一下子回答不上来,不过和第二个题的思路一样,看成刻度,看成分数计算会好很多。总之他们(比如时针和分针)相遇时在固定的某些分数刻度上,计算出来最初的位置和最终的位置,看看哪些分数,比如 1/11、2/11、3/11... 落在了起始位置和最终位置之间,有几个就是相遇多少次。O__O"…

令人震惊的简单算法

坚挺到最后才能发现真相,%>_<%

首先上面有几个数字丫,比如 1:12、1:60、1:720,11次,59 次,719次!59 次是一圈之内分针和秒针相遇的次数,12 小时是多少次呢?59*12 = 60*12 - 12 = 708 次!O__O"…11 次、708 次、719 次 !这是神马玩意?11 + 708 = 719 ?

钟表就是跑道,时针、分针和秒针就是运动员,大家同时出发,12 个小时候又都回到了起点(这是第一次大家都回到起点)。速度之比是1 : 12 : 720,这到底说明了什么呢?时针跑了 1 圈,分针跑了 12 圈,秒针跑了 720 圈。分针多跑了 12-1 圈,多跑一圈就相遇一次丫有木有!!所以,分针和时针相遇 11 次;秒针和分针相遇 720-12 =708 次(这是12个小时内相遇的次数,一小时是 59 次!);秒针和时针相遇 720 - 1 = 719 次!而且刻度很容易计算出来,分别是 1 的 11 等分、59 等分 和 719 等分。为嘛中间那个是 59 等分,不是其他的?12 : 720,实际不是最简比,除以12 (小时),就是 1:60,也就是一圈(一个小时)内的情况。还有就是 B 比 A 多跑了 2 圈,C 比 B 多跑了 3 圈,那么 C 其实就比 A 多跑 2+3 = 5 圈,这就是 11 + 708 = 719 的事实丫!

问题基本到此结束,让 me 们来回答一个看似简单但并不简单,但是可以简单回答的问题。有一个玩具钟表,时针走 3 圈,分针走 4 圈,秒针走 5 圈,问时针走 10 圈,大家的相遇情况?O__O"…,坑爹丫有木有!

速度之比时针:分针:秒针 = 3 : 4 : 5,时针跑了 3 圈,分针跑了 4 圈,秒针跑了 5 圈,时针和分针相遇 4-3=1 次,正好就是终点处;分针比时针多跑了 5-3=2 圈,中间一次是在 3 圈的 1/2 处,也就是时针的 1.5 圈处;秒针比分针也多跑了 1 圈,在最后面有木有。时针的 3 圈是一个循环,大家都乘以 3,然后还有时针走 1 圈的情况,分针比时针在时针的一圈内多跑了 1/3 圈,所以不相遇;秒针比时针多跑了 2/3 圈,所以也不相遇;那秒针比分针多跑多少呢?好吧 3 : 4 : 5 = 1 : 4/3 : 5/3,所以结果很显然了,O__O"…时针的 10 圈以内,时针和分针、分针和秒针、时针和秒针分别相遇 3次、3 次 和 6 次。(这是玩具钟表的答案,应该么有人会断章取义吧,O__O"…)

Game over !


原文链接:http://ilovers.sinaapp.com/drupal/article/2013%E5%B9%B4%E5%A4%A7%E4%BC%97%E7%82%B9%E8%AF%84%E5%AE%9E%E4%B9%A0%E7%94%9F%E6%8B%9B%E8%81%98%E7%AC%94%E8%AF%95%E9%A2%98%E7%9B%AE

原创粉丝点击