趣味面试题集锦

最近看了不少关于求职面试的试题,在其中发现了不少有意思的题目。特整理后发表上来与大家一起分享。

为了方便与以后添加的题目区别,每次更新会以 A B…… 的方式标注。

 

A-1 如何将 a b 的值进行交换,并且不使用任何中间变量?

     解析:一般可以选择两种方式:

     1 )使用加法运算: a = a+b; b = a-b; a = a-b;

     2 )使用异或运算: a = a^b; b = a^b; a = a^b;

其中,如果 a b 的值比较大,那么选择第一种方式可能会导致越界,因此,最佳答案是异或方式。

 

A-2 main 主函数执行完毕后,是否可能会再执行一段代码?

     解析:回答是肯定的。可以使用 atexit() 函数注册一个函数,使得主函数在退出前先执行该注册地函数。

 

A-3 写出下面程序的运行结果

#include #include #define LOOP 1000 int main() { int count = 0,i; int x,y; srand(time(0)); for(i=0;i

解析:据说这是一个很好的概率题。该题中暗含了一个 1/4 圆和一个正方形比较大小的问题。其中, RAND_MAX 是随机数中的最大值,也就是相当于最大半径 R ;而 x y 值则相当于横纵轴的坐标值,它们的平方和开根号就是原点到该点 (x, y) 的距离,当然这个距离可能大于 R 也有可能小于 R

通过上面的分析,该问题则可以蜕化为:随机在正方形里落 LOOP 个点,落在半径里面的点有多少个。鉴于 1/4 圆面积是 (1/4)*π*R*R ,正方形面积是 R*R ,两者之比为 (1/4)*π ,所以落点数为 LOOP*(1/4)*π 个。鉴于题意中 LOOP 1000 ,则可计算出大约为 785 个点。

然而,我 Linux ubuntu 2.6.24-22-generic 运行该程序得到的结果却是 500 左右, Why

 

A-4 :写出下列程序的执行结果:

#include int main() { printf("%f/n", 5); printf("%d/n", 5.01); return 0; }

解析:首先 5 int 型,在 32 平台上会由编译器分配 4 个字节;当以 %f 方式输出时,编译器将从该值所在地址上读出 8 个字节。很显然地,内存访问越界,因此输出结果不确定。同理以 %d 方式显示浮点数 5.01 时,结果也将不确定。从实际测试来说,第一个答案往往是 0.000000 ;第二个很可能是大数。

 

A-5 写出下面程序的执行结果:

#include using namespace std; union { unsigned char a; unsigned int i; } u; int main(void) { u.i = 0xf0f1f2f3; cout<

解析:该程序主要考察内存中数据如何存储。在冯 · 诺依曼体系中,在内存中数据的低位字节存储在低地址上;而数据的地址则采用它的低地址来表示,具体情况如下所示:  

因此该结果将是: f0f1f2f3 f3

 

 

B-1 写出下面程序的执行结果:

#include #include int main(void) { char s[] = "123456789"; char d[] = "123"; strcpy(d,s); printf("%s, %s/n", d, s); return 0; }

解析:这是一个典型的溢出问题。首先数组 s 被分配了 11 个字符(包含字符串串尾的空字符),而数组 d 只被分配了 4 个字符;所以当使用 strcpy() 函数进行字符串复制时,数组 d 会溢出。由于数组 s d 都是自动变量,它们存在于 stack 中,而数组 s 先被分配在高地址上,而数组 d 则被分配在后续的低地址上,当数组 d 越界时,则会造成数组 s 中的数据被覆盖,原来的“ 123456789 则被覆盖为“ 56789/ 0789 其中 ’/0’ 代表字符串尾的空字符。

 

因此,该输出应该是 123456789 56789

 

C-1 :按下面矩阵的输出写出相应的程序:

n=5:
1   2   9 10 25
4   3   8 11 24
5   6   7 12 23
16 15 14 13 22
17 18 19 20 21

n=6:
1   2   9 10 25 26
4   3   8 11 24 27
5   6   7 12 23 28
16 15 14 13 22 29
17 18 19 20 21 30
36 35 34 33 32 31

解析:这是网易有道的一道面试题。貌似在面试中这种类型的题目不少,之前在我的博客中就有一篇关于 螺旋队列 的解析。如果你仔细观察上述输出,就会发现从 1 开始按照大小会排列成蛇形,那么我们姑且把该题目叫做蛇形队列 的算法设计。

如果你是第一次接触这种类型的题目,可以看一下博客中关于 螺旋队列 的解析,这里只写出关键的部分。假定 1 值点所在坐标为 (0, 0 ),横向为 x 轴,以向右为正;纵向为 y 轴,以向下为正。对于任一点 (x, y) ,记 x y 中的绝对值最大者为 A

(1)       A 等于 x 的绝对值。当 A 为奇数时,输出 A 2 +y+1 ;否则,输出 (A+1) 2 -y

(2)       A 等于 y 的绝对值。当 A 为奇数时,输出 (A+1) 2 -x ;否则,输出 A 2 +x+1

 

C-2 36 匹马赛跑,跑道同时只能容许 6 匹马。而且 36 匹马速度不同,但是每次跑的速度恒定。问,跑多少次可以选出第一,第二,第三名。

解析:这同样是网易有道的一道笔试题。在网上已经有不少解答,这里总结一下各种方法:

1 6 次。 36 匹马,每 6 匹一组,对六次赛跑的结果分析,从而得出结论。这是最有争议的办法,但如果从出题者的角度看,这种方法显然无法通过。

2 11 次。 36 匹马,第一组 6 匹马赛完后,淘汰后三名;从剩下的 30 匹马中任选 3 匹进行第二轮,如此循环 … … 1+30%3 = 11

3 8 次。 36 匹马,每 6 匹一组,赛完后取每组的第一名进行第七场赛跑,记录该次比赛的前三名。继而取第一名所在组的第二、第三名,第二名所在组的第一、第二名,第三名所在组的第一、第二名进行第八场赛跑,得出前两名。最终得到结论。

第三种方法最切合出题者的意图。然而如果说裁判的记忆力很差,只能记住一场比赛的结果时,那么显然第三种方法便不是正解了;如果裁判可以记录,那么第一种办法则成为最优解。所以,我认为这个题目本身有多种解答,应该就具体情况具体分析。

 

C-3 :给定一个字串 X ,求它最长字串 S ,使得 S=SR SR S 的反序,即如果 S=abc ,则 SR=cba 。比如: X=abccba ,则输出 S=abc

解析:这是一个典型的查找回文的题目。下面是我自己编写的一个处理程序:

#include #include int main(void) { char in[100]; // 最大处理限长99个字符 int i,j,max,temp; char *p, *tp; printf("Please input string[len<99]: /n"); scanf("%s", in); max = 0; p = NULL; for(i=1;i=0 && (in[i-j]==in[i+j-1]);j++,temp++); // 如果有更大的回文字串,则更新max和 if(temp > max){ max = temp; p = &in[i]; } } if((i+max) > strlen(in)) break; } for(tp=p-max;tp

 

你可能感兴趣的:(趣味集锦)