一步一個腳印筆試面試(二)—google2013年校園招聘筆試題答案
(注:答案全部自己個人,希望指正討論)
1.單項選擇題
1.1 使用C語言將一個1G位元組的字元陣列從頭到尾全部設定為字元'A',在一臺典型的當代PC上,需要花費的CPU時間的數量級最接近:
A. 0.001秒 B. 1秒 C. 100秒 D. 2小時
解答:現在機器cpu都是GHz,每次需要若干個指令,大約在1秒。
1.2 在某些極端要求效能的場合,我們需要對程式進行優化,關於優化,以下說明正確的是:
A. 將程式整個用匯編語言改寫會大大提高程式效能。
B. 在優化前,可以先確定哪部分程式碼最為耗時,然後對這部分程式碼使用匯編語言改寫,使用的彙編語句數目越少,程式就執行越快。
C. 使用匯編語言雖然可能提高程式效能,但是降低了程式的可移植性和可維護性,所以應該絕對避免。
D. 適當調整彙編指令的順序,可以縮短程式執行的時間。
解答:A中,不應該將程式整個改寫,應該只改寫關鍵部分,整個改寫降低了程式的可移植性和可維護性,B,彙編語句不是數目越少越快,迴圈等
C。不應該絕對避免
1.3 對如下c語言程式在普通的x86 pc上面執行時候的輸出敘述正確的是:
char *f()
{
char X[512];
sprintf(X, "hello world");
return X+6;
}
void main()
{
printf("%s",f());
}
A.程式可能崩潰,也可能輸出hello world
B.程式可能崩潰,也可能輸出world
C.程式可能崩潰,也可能輸出hello
D.程式一定會崩潰
解答:
這個程式是想返回一個數組的值,X是一個數組,是函式f()中的一個區域性變數,在這個函式結束的時候,將會釋放掉這個陣列,
而X+6只是一個指向world的一個地址,f()返回的就是這個地址,但是地址中的內容沒有了。
這裡主要是討論的陣列返回的問題參考地址:http://www.cnblogs.com/yangxi/archive/2011/09/18/2180759.html
1.4 方程x1+x2+x3+x4 =30有多少滿足x1>=2,x2>=0,x3>=-5, x4>=8的整數解?
A.3276 B. 3654 C.2925 D.17550
解答:我用程式執行出來是3276,希望知道的給個解答
1.5 一個袋子裡裝了100個蘋果,100個香蕉,100個桔子,100個梨,如果每分鐘從裡面隨機抽取一個水果,那麼最多過多少分鐘時間能肯定至少拿到一打相同種類的水果?(1打=12個)
A. 40 B. 12 C.24 D.45
解答:4中水果都取了11個,用時間4*11=44分鐘,再取一個。45分鐘
1.6 雙敗淘汰賽與淘汰賽相仿,也是負者出局,但負一場後並未被淘汰,只是跌入負者組,在負者組再負者(即總共已負兩場)才被淘汰。現在有10個人參加雙敗淘汰賽,假設我們取消最後的勝者組冠軍VS負者組冠軍的比賽,那麼一個需要舉行多少場比賽?
A. 16 B.17 C.18D.19E.20
解答:10個人需要進行9場產生9個第一次失敗的人,在失敗者的9個人需要8場比賽,淘汰8個人,所以需要9+8=17
1.7 n個節點的二叉樹,最多可以有多少層?
A. n/2 B. log(n)C. n-1D.n
解答:每層一個節點的二叉樹
1.8.
下面哪個序列不是上圖的拓撲排序?
A. ebfgadchB.adbdgfchC.adchebfgD.aedbfgch
解答:
拓撲排序方法如下:
(1)從有向圖中選擇一個沒有前驅(即入度為0)的頂點並且輸出它.
(2)從網中刪去該頂點,並且刪去從該頂點發出的全部有向邊.
(3)重複上述兩步,直到剩餘的網中不再存在沒有前趨的頂點為止.
在C中h應是的g後面的。
1.9假設某主機安裝了2G記憶體,在其上執行的某支援MMU的32位Linux發行版中,一共運行了X,Y,Z三個程序,下面關於三個程式使用記憶體的方式,哪個是可行的?
A.X,Y, Z 的虛擬地址空間都對映到0~4G的虛擬地址上
B.X在堆上分配總大小為1GB的空間,Y在堆上分配200MB,Z在堆上分配500MB,並且記憶體對映訪問一共1GB的磁碟檔案。
C. X 在堆上分配1GB,Y在堆上分配800MB,Z在堆上分配400MB
D.以上訪問方式都是可行的
解答:MMU是記憶體管理單位,A是對的。其它未知,歡迎補充。
1.10當使用TCP協議程式設計是,下列問題哪個是必須由程式設計師考慮和處理的?
A. 亂序資料包的重傳B.資料傳輸過程中的糾錯
C.網路擁塞處理D.發生資料的格式和應用層協議
解答:參考TCP協議功能
2.程式設計和演算法
(2.1,2.2為程式設計題,需要寫出程式實現;2.3為演算法設計題,只需要寫出演算法設計思路及關鍵步驟的虛擬碼即可。)
2.1 給定三個整數a,b,c,實現函式int median(int a, int b, int c),返回三個數的中位數。不可以使用sort,要求整數操作(比較,位執行,加減乘除等)次數儘量少。 並分析說明程式最壞和平均情況下使用的次數。
解答:用了三次比較,一次運算。
程式碼實現:
#include <iostream>
using namespace std;
int median(int a,int b,int c)
{
int min=a;
int max=b;
if (b<min)
{
min=b;
}
else
{
max=b;
}
if (c<min)
{
min=c;
}
else if (c>max)
{
max=c;
}
return a+b+c-min-max;
}
int main()
{
cout<<median(2,1,3);
}
2.2 給定一個key(只含有ASCII編碼的小寫英文字母),例如kof,然後對input的string(只含有ASCII編碼的小寫英文字元)利用這個key排序。順序是:先按照key中的字元排序,然後對key中不包含的字元,按a-z排序;
解答:
思路:(1)用hash表的思想,先對key字和a~z重新排序,可以定義一個26個字元的陣列,char hash[26]; 對不同的字母對應的給與排序的值,
例如key中為kof,得到的hash['k'-97]=0; hash['o'-97]=1;hash['f'-97]=2;hash['a'-97]=3;..................
(2)用快速排序(已可以是其他演算法)演算法進行排序
程式碼實現:
#include <iostream>
#include <string.h>
using namespace std;
void swap(char* a,char* b)
{
char temp=*a;
*a=*b;
*b=temp;
}
void create_hash(char* hashtable,char* key)
{
int iKeyLength=strlen(key);
int iValue=0;
for (int i=0;i<26;i++)
{
hashtable[i]='#';
}
//先對關鍵字元排在前面
for (int i=0;i<iKeyLength;i++)
{
hashtable[*(key+i)-97]=iValue;
iValue++;
}
//對剩餘的字元進行排列
for (int i=0;i<26;i++)
{
if (hashtable[i]=='#') //其中的hashtable[i]==hashtable['a'+i-97]
{
hashtable[i]=iValue;
iValue++;
}
}
}
//快速排序
void quick_sort(char* str,int iStart,int iEnd,char* hashtable)
{
if (iStart>=iEnd)
{
return ;
}
char* pSign=str+iStart; //將第一個作為劃分標誌
char* pMove=str+iEnd; //需要比較移動的點
char* pTemp;
while(pSign!=pMove)
{
if (pMove>pSign)
{
if (hashtable[*pSign-97]>hashtable[*pMove-97])
{
swap(pSign,pMove); //交換值
pTemp=pMove; //交換指標
pMove=pSign;
pSign=pTemp;
pMove++;
}
else
{
pMove--;
}
}
else
{
if (hashtable[*pSign-97]<hashtable[*pMove-97])
{
swap(pSign,pMove); //交換值
pTemp=pMove; //交換指標
pMove=pSign;
pSign=pTemp;
pMove--;
}
else
{
pMove++;
}
}
}
quick_sort(str,iStart,pSign-1-str,hashtable);
quick_sort(str,pSign+1-str,iEnd,hashtable);
}
void sort(char* str,char* key)
{
char hashTable[26];
create_hash(hashTable,key);
quick_sort(str,0,strlen(str)-1,hashTable);
}
int main()
{
char str[]="helloworld";
char key[]="kol";
sort(str,key);
cout<<str<<endl;
}
2.3 一個平行於座標軸的n*n的網格,左下角(0,0)右上角(n,n),n為非負整數,有n個平行於座標軸的矩形,每個矩形用左下角(x1,y1)右上角(x2,y2)來表示,x1,y1,x2,y2都是非負整數,現在有非常多個query,每個query會詢問一個網格(x,y)(x+1,y+1)一個被幾個矩形覆蓋。現在要求設計一個演算法,使得出來每個query的時間複雜度儘可能低,在這個前提下,預處理的時間複雜度儘可能低。
(1<=n<=1000)