虽然过了两个星期 不过终于有时间整理一下之前腾讯笔试的问题了。很遗憾,因为没有复习所以去到各种不会~现在回想起来还是很多题目没有仔细想的。印象比较深刻的是下面几题,跟编程相关的只有几题。。。

 

1.如图所示,一个8x6大小的方格中,从A点到B点而且不经过C点共有多少种走法,只允许向上或者向右走

这一题,一开始的想法就是任意一格的走法都等于它左边走法(如果存在)跟下边走法(如果存在)的和,用表达式x表示水平,y表示竖直,A位置为(0,0)的话,B位置为(7,5),f(x,y)表示A到点(x,y)的走法,那么有 x=0时f(x,y)=f(x,y-1) ,y=0时f(x,y)=f(x-1,y),x!=3&&y!=3时f(x,y)=f(x-1,y)+f(x,y-1)。只需要从f(7,5)慢慢写下来就可以了,这样写很容易出错(事实上我就是在这里写错了一直没搞对),后来我想到更简单的方法,如图所示

 

只需要给每一个格子都算出对应的步数就可以了,其中C可以直接跳过,所以答案应该是492

 

2.这一题我到现在都没算到对应的答案,我算出来的答案根本没有这个选项囧

题目是这样的:图书馆有三个人借书,三个人还书,三本书是一样的,要保证借书的时候能借到,问这样的排列数是多少?

我的思路是这样的,三个人借书三个人还书,那么第一个人一定是还书,最后一个人一定是借书,这样的情况应该是3x3=9;

剩下的四个人,可以是以下顺序,还借还借,借还借还,还还借借,借还还借,还借借还,应该只有这五种情况了吧?所以应该是9x5x2x2=180.咦怎么有这个选项。不知道对不对呢。可能就是180了。反正那时候我就选180

 

3.还有一题比较有趣,我的思路可能是对的,但是碍于时间,还有看错一点点题,最后答案没有算对。其实我也不确定是猜小还是猜大了。。。

题目是这样的:一个猜1-100的数字的游戏,规则是这样的,如果你猜的数比实际数(这里我就看错了!),那么会告诉你你猜的数较小,如果你猜的数比实际数大,那么只会告诉你猜对还是猜错而且以后都再不告诉你是大是小。

问至少要多少次可以保证能猜到这个数,一开始猜的数是多少?

很多人(包括我一开始)都会想第一个数是50啦,不用想了。但是我用了几秒钟就否定了这个想法,如果猜中位数而且猜了相反方向(按照这题如果实际的数比较小),那么你就失去通过猜测缩小数的范围了。要想一个方法是在猜的过程中保证每次都可以减少猜的数的范围,又可以保证即使猜的数太大实际之后要猜的范围很小。所以我的想法是第一个数是10,第二个数是20,第三个数是30这样递增下去,但是,这样的想法有个问题,假如要猜的数是99的话,我猜的顺序是10,20,30,……,100虽然我每次都猜对并缩小了范围,但是最坏情况下,要猜20次。于是就诞生了下一个想法,是不是应该每次猜的范围是变化的,而且范围越猜越小,这样可以保证即使数字较大,最后猜的范围可以较小。考虑我最后的区间是1,即最后一个数是100,前一个猜的数是99,再往前应该是97,94,90,85,79,72,64,55,45,34,22,9,1,其中,每个数的间隔(从后往前)是1,2,3,4,5,6,7,8,9,10,11,12,13,8,当然要有必要调整一下顺序,让间隔是递减的,间隔为13,12,11,10,9,8,8,7,6,5,4,3,2,1, 猜的数是从后往前应该是100,99,97,94,90,85,79,72,64,56,47,37,26,14,1,再调整下应该是13,25,36,46,55,63,71,78,84,89,93,96,98,100,那么每个区间最多要猜12,11,10,9,8,8,7,6,5,4,3,2,2次,所以最后每个区间要猜的次数是13,13,13,13,13,14,14,14,14,14,14,14,15次。可能答案是15次?第一个数是13?

这题真不确定答案~

 

4.还有一题编程的,其实蛮简单的,但没想出来,数组A存放非0的数,有n个元素。数组B[i] = A[0]xA[1]x…xA[i-1]xA[i+1]x…xA[n-1]。不用任何其余空间,不用除法,用最快的时间保存数组B的值

可以把B展开

B[0]= A[1]XA[2]XA[3]XA[4]X…XA[n-1]

B[1]=A[0]X A[2]XA[3]XA[4]X…XA[n-1]

B[2]=A[0]XA[1]X A[3]XA[4]X…XA[n-1]

B[3]=A[0]XA[1]XA[2]X A[4]X…XA[n-1]

B[4]=A[0]XA[1]XA[2]XA[3]X …XA[n-1]

B[n-2]= A[0]XA[1]XA[2]XA[3]XA[4]X…XA[n-3]x xA[n-1]

B[n-1]= A[0]XA[1]XA[2]XA[3]XA[4]X…XA[n-2]

可以把程序分成两步,首先,让i=1…n-1,让B[i]保存A[0]到A[i-1]的乘积,就是

  1. B[0]=A[0];  
  2.   
  3. for(i = 1; i < n; i++)   
  4.   
  5. B[i] = B[i-1]*A[i-1]; 

然后,让i=n-2…0, 用B[i]保存A[i-1]到A[1]的乘积,就是

 

  1. B[0]=A[n-1];
  2. for(i = n-2;i>0;i—) {
  3. B[i] *= B[0];
  4.  B[0] *=A[i];

应该是这样吧。

代码如下

  1. B[0]=A[0]; 
  2.  
  3. for(i = 1; i < n; i++)  
  4.  
  5. B[i] = B[i-1]*A[i-1]; 
  6.  
  7.  
  8.  
  9. B[0]=A[n-1]; 
  10.  
  11. for(i = n-2;i>0;i—) { 
  12.  
  13. B[i] *= B[0];  
  14.  
  15. B[0] *=A[i]; 
  16.