腾讯2015研发笔试大题

来源:互联网 发布:生产成本管控数据来源 编辑:程序博客网 时间:2024/05/22 01:48

1.递归实现格雷码
感觉这道题完全是考察对格雷码规律熟悉程度。如果能够能够比较清楚的知道这点,代码实现比较简单。具体格雷码如下:
1位格雷码 0 1
2位格雷码 00 01 11 10
3位格雷码 000 001 011 010 110 111 101 100
4位格雷码 0000 0001 0011 0010 0110 0111 0101 0100
1100 1101 1111 1110 1010 1011 1001 1000

从上面的书写过程中可以看出如下规律:
1)N位格雷码有2^N个;
2)1位格雷码只有 0 和 1;
3)N位格雷码前2^(N-1)个是把N-1位格雷码顺序抄写下来,并在高位加0;(如果用整形表示格雷码,高位加0数值不变,只需要顺序抄写下来就可以了)
4)N位格雷码后2^(N-1)个是把N-1位格雷码逆序抄写下来,并在高位加1;(如果用整形表示格雷码,高位加1,可以直接用数值加上2^(N-1))
有了上述规律写起递归来就很简单了:

vector<int> getGrayCode(int n){    vector<int> vc;    vc.push_back(0);    if(n == 0) return vc;//输出判断    if(n == 1)    {        vc.push_back(1);        return vc;    }    int GrayCodeCount = pow(2.0,n);    getGrayCode(n-1);//处理n-1位格雷码的生成     for(int i=GaryCodeCount>>1;i<GrayCodeCount;++i)    {        vc.push_back(vc[GrayCodeCount - i -1] + (GrayCodeCount>>1));//处理格雷码的后2^(N-1)位    }    return vc;}

一点思考:记得笔试题上说要考虑健壮性,应该是提醒考虑大数的情况。这里最好应该用字符串来保存生成的隔离码。

2.九宫格
题目大概是这样的:
A + B - 9 = 4
+ - -
C - D * E = 4
/ * -
F + G - H = 4
= = =
4 4 4
问每个变量的取值都在0~100之间,编程实现找所有变量的取值。
这题感觉就是考数学,可惜做的时候没有认真的想。下面是我的分析思路:
A<=4 B=15-A <– A+B-9=4
H<=5 E=5-H <– 9-E-H=4
F>=1&&F<=25 <– A+C/F=4 C<=100
E D G != 0 <– 等于0时不满足条件
有了上面的分析就可以很容易的写出代码了:

int main(){    int A,B,C,D,E,F,G,H;    for(A=0;A<=4;++A)    {        B = 15 - A;        for(H=0;H<=5;++H)        {            E = 5 - H;            //if(E == 0for(F=1;F<=25;++F)            {                C = (4-A)*F;                if(C>=0  && C <= 100 && E != 0)                {                    if((C-4)%E == 0)                    {                        D = (C-4)/E;                        if(D>0 && D<=100)                        {                            if((B-4)%D == 0)                            {                                G = (B-4)/D;                                if(G>=0 && G<=100)                                    cout<<"A="<<A<<" "                                        <<"B="<<B<<" "                                        <<"C="<<C<<" "                                        <<"D="<<D<<" "                                        <<"E="<<E<<" "                                        <<"F="<<F<<" "                                        <<"G="<<G<<" "                                        <<"H="<<H<<" "                                        <<endl;                            }                        }                    }                }            }        }    }    return 0;}

一点思考:总觉得腾讯出这种题不会这么简单,不知道有没有更好的方法。

3.进程的同步互斥问题
题目大概是这样描述的:有三个进程Producer,Transmitter,Consumer。其中Producer负责将信息不断地输入ProduceBuf,Transmitter负责从ProduceBuf取信息进行处理,并将处理结果送至ConsumBuf,Consumer负责从ConsumBuf中读取结果。(好像没有提每个Buf同一时刻只能有一个进程访问,反正我是默认了)。假设ProduceBuf可以放12个信息,现在已经放了3个,ConsumBuf最多可放6个信息,要求写出正确的同步互斥算法。
这个过程我认为关键在Transmiter这个进程,如果ConsumBuf已经满了,不应从ProduceBuf里取信息,保证一旦从ProduceBuf里取出信息那么就一定能放入ConsumBuf。

PBufEmpty = 9; //ProduceBuf 可用数目PBufFull = 3; //ProduceBuf 已用数目CBufEmpty = 6; //ConsumBuf 可用数目CBufFull = 0; //ConsumBuf 已用数目PMutex = 1,CMutex = 1;//控制资源互斥访问void Produce()   //Producer 进程{    while(1)    {        P(PBufEmpty);//我要来存资源,有可用空间吗?        P(PMutex);//我现在能访问PBuf吗?            putPBuf();//有可用的空间,抢到了PBuf的访问权        V(PMuxtex); //释放我的访问权        V(PBufFull); //增加已用数目    }}void Consumer()  //Consumer  进程{    while(1)    {        P(CBufFull);// 我要取资源,空间里有资源吗?        P(CMutex);// 我现在能访问CBuf吗?            getCBuf();// 空间有资源,抢到了CBuf的访问权        V(CMutex);// 释放我的访问权        V(PBufEmpty); // 增加可用空间的数目    }}void Transmitter()  //Transmitter 进程{    while(1)    {        P(CBufEmpty); // 我要存资源,CBuf有剩余空间吗?(一旦有空间我就不担心了,因为剩余空间只会增多)        P(PBufFull);// 我要取资源,PBuf里有资源吗?(一旦有资源我就不担心了,因为资源数只会增多)        P(PMutex);// 很放心的来抢我的PBuf访问权。            getPBuf(); //取出资源来        V(PBufEmpty);// 增加可用空间        V(VMutex);// 赶紧归还我的访问权          P(CMutex);// 很放心的来抢我的CBuf访问权。            putCBuf();//放入资源        V(CBufFull);// 增加资源数量        V(CMutex);//归还我的访问权      }}

参考:

http://www.infoq.com/cn/articles/producers-and-consumers-mode
http://www.cnblogs.com/clover-toeic/p/4029269.html
http://c.biancheng.net/cpp/html/2600.html

4、找出在序列中出现超过一半以上的数字
这题是《剑指office》上的原题,可惜当时只想记得用快排的方法来做。书上记录了一种更好的方法,根据数字出现次数与序列个数的关系:超过一半表示相同元素的个数,比其他元素个数至少多1。可以写出如下算法思路:
1)定义一个计数器count = 1,并记录当前的元素为key;
2)遍历序列,如果下一个元素与key不相同则count–;相同则count++;
3)当count==0时,将当前元素重新赋值为key,并令count=1。
这样最后的key就是我们要求得元素。
代码实现:

int findNum(int* arr,int len){    if(arr == NULL || len<=0) return -1;    int count = 1,key=arr[0];    for(int i=1;i<len;++i)    {        if(count == 0)         {            key = arr[i];            count = 1;        }        else if(key == arr[i]) count++;        else count--;    }    //当然最后要验证一下key是不是真的出现了一半以上    count = 0;    for(int i=0;i<len;++i)    {        if(key == arr[i]) count++;    }    if(count < len/2) return -1;    return key;}

总结:现在看来腾讯的几道笔试题考察的非常基础,不是很难。可惜自己发挥的不是很好,感觉与腾讯无缘了~~~

0 0
原创粉丝点击