1. 程式人生 > >2012百度實習生招聘面試題

2012百度實習生招聘面試題

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

                一面:
第一題、任意給一個數,試證明這個數的某個倍數的十進位制表示是01串,比如3的倍數111是二進位制表示,5的倍數10是二進位制表示,等等。
假設序列1,11,111,1111…用A1~AN標識,下腳標N即為1的個數,如:A1=1,A2=11,A3=111…
其中沒有一個是N的倍數,即AK mod N不等於0(K屬於1~N),並且AK mod N的餘數各不相同,設它們為a1,a2,a3,…,aN,但AK mod N的餘數最多隻有N-1個不同,則由鴿巢原理可知,a1,a2,a3,…,aN中必有兩個相同,即ai=aj(j>i),則Aj-Ai=0(mod N),Aj-Ai即為所求的0和1組成的十進位制數M,得證。

第二題、證明素數有無窮多個。
     假若素數只有有限多個,設最大的一個是P,從2到P的全體素數是:
  2,3,5,7,11……,P。
  所有的素數都在這裡,此外再沒有別的素數了。
  現在,我們來考察上面從2到P的全體素數相乘、再加上1這個數,設它是A,即
  A=2×3×5×7×11×……×P+1。
  A是一個大於1的正整數,它不是素數,就是合數。
  如果A是素數,那麼,就得到了一個比素數P還要大的素數,這與素數P是最大素數的假設矛盾。
  如果A是合數,那麼,它一定能夠被某個素數整除,設它能被g整除。
  因為A被從2到P的任何一個素數除,餘數都是1,就是都不能整除,而素數g是能整除A的,所以素數g不在從2到P的全體素數之中。這說明素數g是一個比素數P更大的素數,這又與P是最大的素數的假設矛盾。
  上面的證明否定了素數只有有限多個的假定,這就證明了素數是無窮多個。

第三題、給一個很大的陣列,裡面有兩個數只出現過一次,其他數都出現過兩次,把這兩個數找出來。
很簡單,根據所有數的異或結果,將數字分為兩組,然後找出這兩個數。前面我的blog裡有這個題的介紹的。
第四題、把一個連結串列逆過來,要求空間複雜度O(1),這個算簡單的。
/*==========================功能:連結串列逆序(連結串列的頭變成連結串列的尾,連結串列的尾變成頭)返回:指向連結串列表頭的指標==========================*/struct node *Reverse (struct node *head)struct node *p;         //臨時儲存
 struct node *p1;        //儲存返回結果 struct node *p2;        //源結果節點一個一個取 p1 = NULL;            //開始顛倒時,已顛倒的部分為空 p2 = head;            //p2指向連結串列的頭節點 while(p2 != NULL) {  p = p2->next;  p2->next = p1;  p1 = p2;  p2 = p; } head = p1; return head;}

二面:
1、是如何統計程式碼行數以及註釋的行數,並寫出具體的實現程式碼。
程式碼行數是按照\n數的,行註釋//需要注意//...\n算一個註釋,但注意//...\n之間的//與/**/不算註釋。
/**/要注意/* /* */ 等於一個註釋, 也就是一旦遇見/*之後就要記下來,一直匹配到*/才算一個完整的註釋,中間的內容隨便它是什麼,包括//可能也巢狀在其中。

2、要求用最快的速度求兩個陣列的交集,提示陣列中的元素是無序的。寫出具體的實現程式碼。
如果雜湊真的是O(1)的,那麼可以達到O(n+m),否則就是nlogn + mlogm。
3、寫程式,將一個浮點數轉化為字串。。
先將浮點數賦值給一個int型別的整數,然後分別將整數部分、小數部分轉化為字串就可以了。
4、下面兩個printf的輸出結果是什麼?為什麼會有這樣的結果?
int main(void)char a = 255printf("%d\n",sizeof(++a)); printf("%d\n",a); return 0;}
輸出結果是:1               -1
第一個輸出的是字元型別佔用的記憶體大小,一個字元型別佔用一個位元組的大小,所以輸出1
由於255的二進位制表示是1111 1111,將其作為int型別輸出的時候,由於最高位是1,表示的是一個負數,其表示的數字就是將最高位後面的7個1取反後在加上1,表示的就是-1,所以第二個輸出應該是-1。

5、下面程式碼的輸出是什麼?
char *c[] = {"ENTER","NEW","POINT","FIRST"};char **cp[] = { c + 3 , c + 2 , c + 1 , c};char ***cpp = cp;int main(void)printf("%s",**++cpp); printf("%s",*--*++cpp+3); printf("%s",*cpp[-2]+3); printf("%s\n",cpp[-1][-1]+1); return 0;}
c是一個指標陣列,一個數組,元素是char*型別的指標,值分別是那些字串(的首地址)
c[0] = "ENTER"
c[1] = "NEW"
c[2] = "POINT"
c[3] = "FIRST"
而[]和*是本質一樣的運算,即c[i]=*(c+i)
c和c+i都是char *[]型別,它可以退化成char **型別,再看cp,它正好是一個char **的陣列,來看它的值:
cp[0] = c + 3
cp[1] = c + 2
cp[2] = c + 1
cp[3] = c
再引用一次看得清楚些
cp[0][0]=c[3]="FIRST",etc
cp是char **[]型別,它可以退化成char ***型別,看最後的cpp,它正是char ***型別,它是一個指標變數,和上面兩個不同,上面兩個是陣列。

1、printf("%s",**++cpp);
++cpp 的值是cp+1,引用一次後是cp[1]再引用是*cp[1]=c[2]="POINT",第一句的輸出
2、printf("%s",*--*++cpp+3);
再++cpp 的值是cp+2,引用一次是cp[2]=c+1,再對這進行--,減後是c再引用是c[0]="ENTER"再+3,字串指標指到"ER",輸出是"ER"
3、printf("%s",*cpp[-2]+3);
這時cpp的值是cp+2,cpp[-2]=*(cpp-2)=*(cp+2-2)=cp[0]=c+3,再引用是c[3]="FIRST",+3 字串指標指到"ST",輸出是"ST"
4、printf("%s\n",cpp[-1][-1]+1);
cpp還是cp+2,cpp[-1]=*(cpp-1)=*(cp+2-1)=cp[1]=c+2,再[-1]得*(c+2-1)=c[1]="NEW",+1字串指標指到"EW",輸出是"EW"


三面:
1、給定兩個排好序的陣列A和B
,他們中的元素個數都是n,求他們所有元素的中位數。要求:時間複雜度為O(logn),空間複雜度為O(1)。(二分查詢)
http://blog.csdn.net/hackbuteer1/article/details/7584838    實現程式碼
2、有兩個陣列a、b,大小都為n,陣列中元素的值是整數型別、無序;要求:通過交換a,b中的元素,使陣列a元素的和與陣列b元素的和之間的差最小?
3、對已排好序的陣列A,一般來說可用二分查詢可以很快找到。現有一特殊陣列A[],它是迴圈遞增的,如A[]={ 17 19 20 25 1 4 7 9},
試在這樣的陣列中找一元素x,看看是否存在。
請寫出你的演算法,必要時可寫虛擬碼,並分析其空間、時間複雜度。
http://blog.csdn.net/hackbuteer1/article/details/7581596      實現程式碼
           

給我老師的人工智慧教程打call!http://blog.csdn.net/jiangjunshow

這裡寫圖片描述