[实战演练]2014年人人公司应届生校招技术笔试题
一,客观题
1. 下面哪种排序比较适合对基本有序的数组进行排序()
A 插入排序 B 快速排序 C 堆排序 D 归并排序
2. 下面哪种排序算法的平均时间复杂度最低()
A 快速排序 B 桶排序 C 希尔排序 D 堆排序
3. 假设一棵二叉树的后序遍历序列为BJDCFGEIHA,中序遍历序列为BCDJAFEGHI,则其前序遍历序列为()
A ACBDEGHJFI B ACBDJHEFGI
C ACBDEGJHFI D ABCDEFGHIJ
4. 一块矩形巧克力,初始时由N*M个小块组成。每一次你只能把一块巧克力掰成两个小矩形。最少需要几次才能把它们掰成N*M块1*1的小巧克力?
A N*M-1 B N*M
C logN*M D logM*N
5. 以下程序的输出结果是()
1 int main() 2 { 3 int i, sum; 4 for(i=2;i<6;i++) 5 { 6 sum += i*(i-1); 7 } 8 printf("%d\n",sum); 9 }
A 40 B 70 C 无法确定 D 0
6. 以下程序的输出结果是
1 int main() 2 { 3 char a[]={20,19,18,17,16,15,14,13,12,11}; 4 char* p=a+5; 5 printf("%d",*--p); 6 }
A 程序非法退出 B 16 C 15 D 14这个元素对应的内存地址
7. 假定a和b为int型变量,以下代码的输出为()
a=1;b=10;do{b -= a; a++;}while(b--<0);
A 9 B -2 C -1 D 8
8. 67的23次方与4取模的结果是()
A 3 B 2 C 1 D 0
9. 在区间[-1,1]随意取两个数,它们的和大于1的概率是()
A 1/2 B 1/4 C 1/8 D 1/16
10. 考虑一个双人游戏,游戏在一个圆桌上进行。每个游戏者都有足够多的硬币。他们需要在桌子上轮流放置硬币,每次必需且只能放置一枚硬币,要求硬币完全置于桌面内(不能有一部分悬在桌子外面),并且不能与原来放过的硬币重叠。谁没有地方放置新的硬币,谁就输了。游戏的先行者还是后行者有必胜策略?
A 先行者必胜 B 后行者必胜 C 有必胜策略,但和先行后行无关 D 不确定
二、主观题
1. 给定一个有序数组a,长度为len,和一个数X,判断A数组里面是否存在两个数,他们的和为X。bool judge(int *a, int len, int x),若存在则返回true,不存在则返回false。
2. 给定有n个数的数组a,其中超过一半的数为一个定值,在不进行排序、不开设额外数组的情况下,以最高效的算法找到这个数:int find(int* a, int n);
3.(略)
我的解答:
客观题
1. A 插入排序
2. B 桶排序
3. B 可以画出这棵树的结构,然后再求前序遍历
4. A 观察到,每掰一次,巧克力数量只能增加1。不存在这种掰法,使得掰一次多了两个或更多块巧克力。
5. C sum没有初始化,在VS 2010里面测试的结果是先报出来一个警告,警告sum未初始化;无视警告继续执行,输出一个绝对值特别大的负数。因此这道题目选择C。出于好奇,我又尝试将sum放在main函数外面,作为一个全局变量,则输出结果是40,也就是说这种情况下,sum不初始化,则系统默认初始化为0.
6. B 输出为16,也就是p先自减1,然后再输出;如果“--”放在p后面,改成printf("%d", *p--);则输出结果就是15了。
7. D 输出为8,这道题目说的不清楚,应该是在问b的值,即printf("%d", b);的输出
8. A 余数是3.考察二项分布,原题可以看成(68-1)^23.将这个式子二项展开,第i项为 C(i, 23) *68^i * (-1)^(23-i),其中i=0,1,2,3,...,23。所有含有68的项都可以被4整除,只有第0项,为-1.也就是说67的23次方结果等于一个能被四整除的数减一,那除以4肯定余数是3。
9. C
10. A 先行者第一步放在圆桌正中间一颗硬币,后面的选手不管放在什么位置,这个先行者总是放在其关于圆心对称的位置,则必胜。
主观题
1. 思路:将数列排序,然后从最小的开始,比如最小的数是k,要找的和为x,则在剩下的数列中用二分查找法找是否存在(x-k),不存在则检测下一个第二小的数,直到找到为止。排序复杂度 O(nlogn),后面这一步复杂度也是O(nlogn),总体复杂度就是O(nlogn)。代码等有时间了再写……
2. 思路:如果超过一半的数是定值,那么去掉两个不一样的数以后,那个定值还是超过一半,通过这种方法可以找到。复杂度是O(n)。代码等有时间了再写……