1. 程式人生 > >一步一個腳印筆試面試(二)—google2013年校園招聘筆試題答案

一步一個腳印筆試面試(二)—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)