版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
Python程序員面試分類真題19(總分:100.00,做題時(shí)間:90分鐘)面試題(總題數(shù):7,分?jǐn)?shù):100.00)1.
用1、2、2、3、4、5這六個(gè)數(shù)字,寫一個(gè)main函數(shù),打印出所有不同的排列,例如:512234、412345等,要求:“4”不能在第三位,“3”與“5”不能相連。
(分?jǐn)?shù):14.00)__________________________________________________________________________________________
正確答案:(打印數(shù)字的排列組合方式的最簡單的方法就是遞歸,但本題存在兩個(gè)難點(diǎn):第一,數(shù)字中存在重復(fù)數(shù)字,第二,明確規(guī)定了某些位的特性。顯然,采用常規(guī)的求解方法似乎不能完全適用了。
其實(shí),可以換一種思維,把求解這6個(gè)數(shù)字的排列組合問題轉(zhuǎn)換為大家都熟悉的圖的遍歷的問題,解答起來就容易多了。可以把1、2、2、3、4、5這6個(gè)數(shù)看成是圖的6個(gè)結(jié)點(diǎn),對這6個(gè)結(jié)點(diǎn)兩兩相連可以組成一個(gè)無向連通圖,這6個(gè)數(shù)對應(yīng)的全排列等價(jià)于從這個(gè)圖中各個(gè)結(jié)點(diǎn)出發(fā)深度優(yōu)先遍歷這個(gè)圖中所有可能路徑所組成的數(shù)字集合。例如,從結(jié)點(diǎn)“1”出發(fā)所有的遍歷路徑組成了以“1”開頭的所有數(shù)字的組合。由于“3”與“5”不能相連,因此,在構(gòu)造圖的時(shí)候使圖中“3”和“5”對應(yīng)的結(jié)點(diǎn)不連通就可以滿足這個(gè)條件。對于“4”不能在第三位,可以在遍歷結(jié)束后判斷是否滿足這個(gè)條件。
具體而言,實(shí)現(xiàn)步驟如下所示:
(1)用1、2、2、3、4、5這6個(gè)數(shù)作為6個(gè)結(jié)點(diǎn),構(gòu)造一個(gè)無向連通圖。除了“3”與“5”不連通外,其他的所有結(jié)點(diǎn)都兩兩相連。
(2)分別從這6個(gè)結(jié)點(diǎn)出發(fā)對圖做深度優(yōu)先遍歷。每次遍歷完所有結(jié)點(diǎn)的時(shí)候,把遍歷的路徑對應(yīng)數(shù)字的組合記錄下來,如果這個(gè)數(shù)字的第三位不是“4”,那么把這個(gè)數(shù)字存放到集合Set中(由于這6個(gè)數(shù)中有重復(fù)的數(shù),因此,最終的組合肯定也會有重復(fù)的。由于集合Set的特點(diǎn)為集合中的元素是唯一的,不能有重復(fù)的元素,因此,通過把組合的結(jié)果放到Set中可以過濾掉重復(fù)的組合)。
(3)遍歷Set集合,打印出集合中所有的結(jié)果,這些結(jié)果就是本問題的答案。
實(shí)現(xiàn)代碼如下:
classTest:
def__init__(self,arr):
#self.numbers=[1,2,2,3,4,5]
self.numbers=arr
#用來標(biāo)記圖中結(jié)點(diǎn)是否被遍歷過
self.visited=[None]*len(self.numbers)
#圖的二維數(shù)組表示
self.graph=[([None]*len(self.numbers))foriinrange(len(self.numbers))]
self.n=6
#用來標(biāo)記圖中結(jié)點(diǎn)是否被遍歷過
#self.visited=None
#圖的二維數(shù)組表示
#self.graph=None
#數(shù)字的組合
bination="
#存放所有的組合
self.s=set()
"""
**方法功能:對圖從結(jié)點(diǎn)start位置開始進(jìn)行深度遍歷
**輸入?yún)?shù):start:遍歷的起始位置
"""
defdepthFirstSearch(self,start):
self.visited[start]=True
bination+=str(self.numbers[start])
iflen(bination)==self.n:
#4不出現(xiàn)在第三個(gè)位置
ifbination.index("4")!=2:
self.s.add((bination))
j=0
whilej<self.n:
ifself.graph[start][j]==1andself.visited[j]=False:
self.depthFirstSearch(j)
j+=1
bination=bination[:-1]
self.visited[start]=False
#方法功能:獲取1、2、2、3、4、5的左右組合,使得"4"不能在第三位,"3"與"5"不能相連
defgetAllCombinations(self):
#構(gòu)造圖
i=0
whilei<self,n:
j=0
whilej<self.n:
ifi==j:
self.graph[i][j]=0
else:
self.graph[i][j]=1
j+=1
i+=1
#確保在遍歷的時(shí)候3與5是不可達(dá)的
self.graph[3][5]=0
self.graph[5][3]=0
#分別從不同的結(jié)點(diǎn)出發(fā)深度遍歷圖
i=0
whilei<self.n:
self.depthFirstSearch(i)
i+=1
defprintAllCombinations(self):
forstrsinself.s:
printstrs,
if__name__=="__main__":
arr=[1,2,2,3,4,5]
t=Test(arr)
t.getAllCombinations()
#打印所有組合
t.printAllCombinations()
由于結(jié)果過多,因此這里就不列出詳細(xì)的運(yùn)行結(jié)果了。)解析:[考點(diǎn)]如何求數(shù)字的組合。2.
10個(gè)房間里放著數(shù)量隨機(jī)的金幣。每個(gè)房間只能進(jìn)入一次,并只能在一個(gè)房間中拿金幣。一個(gè)人采取如下策略:前4個(gè)房間只看不拿。隨后的房間只要看到比前4個(gè)房間都多的金幣數(shù),就拿。否則就拿最后一個(gè)房間的金幣。編程計(jì)算這種策略拿到最多金幣的概率。
(分?jǐn)?shù):14.00)__________________________________________________________________________________________
正確答案:(這道題要求一個(gè)概率的問題,由于10個(gè)房間里放的金幣的數(shù)量是隨機(jī)的,因此,在編程實(shí)現(xiàn)的時(shí)候首先需要生成10個(gè)隨機(jī)數(shù)來模擬10個(gè)房間里金幣的數(shù)量。然后判斷通過這種策略是否能邑拿到最多的金幣。如果僅僅通過一次模擬來求拿到最多金幣的概率顯然是不準(zhǔn)確的,那么就需要進(jìn)行多次模擬,通過記錄模擬的次數(shù)m,拿到最多金幣的次數(shù)n,從而可以計(jì)算出拿到最多金幣的概率n/m。顯然這個(gè)概率與金幣的數(shù)量以及模擬的次數(shù)有關(guān)系。模擬的次數(shù)越多越能接近真實(shí)值。下面以金幣數(shù)為1到10的隨機(jī)數(shù),模擬次數(shù)為1000次為例給出實(shí)現(xiàn)代碼:
importrandom
"""
方法功能:總共n個(gè)房間,判斷用指定的策略是否能拿到最多金幣
返回值:如果能拿到返回True,否則返回False
"""
defgetMaxNum(n):
ifn<1:
print"參數(shù)不合法"
return
a=[None]*n
#隨機(jī)生成n個(gè)房問里金幣的個(gè)數(shù)
i=0
whilei<n:
a[i]=random.uniform(1,n)#生成1~n的隨機(jī)數(shù)
i+=1
#找出前四個(gè)房間中最多的金幣個(gè)數(shù)
max4=0
i=0
whilei<4:
ifa[i]>max4:
max4=a[i]
i+=1
i=4
whilei<n-1:
ifa[i]>max4:#能拿到最多的金幣
returnTrue
i+=1
returnFalse#不能拿到最多的金幣
if__name__=="__main__":
monitorCount=1000+0.0
success=0
i=0
whilei<monitorCount:
ifgetMaxNum(10):
success+=1
i+=1
printsuccess/monitorCount
程序的運(yùn)行結(jié)果為:
0.421
運(yùn)行結(jié)果分析:
運(yùn)行結(jié)果與金幣個(gè)數(shù)的選擇以及模擬的次數(shù)都有關(guān)系,而且由于是個(gè)隨機(jī)問題,因此同樣的程序每次的運(yùn)行結(jié)果也會不同。)解析:[考點(diǎn)]如何拿到最多金幣。3.
給定一個(gè)正整數(shù)n,求解出所有和為n的整數(shù)組合,要求組合按照遞增方式展示,而且唯一。例如:4=1+1+1+1、1+1+2、1+3、2+2、4(4+0)。
(分?jǐn)?shù):14.00)__________________________________________________________________________________________
正確答案:(以數(shù)值4為例,和為4的所有的整數(shù)組合一定都小于4(1,2,3,4)。首先選擇數(shù)字1,然后用遞歸的方法求和為3(4-1)的組合,一直遞歸下去直到用遞歸求和為0的組合的時(shí)候,所選的數(shù)字序列就是一個(gè)和為4的數(shù)字組合。然后第二次選擇2,接著用遞歸求和為2(4-2)的組合;同理下一次選3,然后用遞歸求和為1(4-3)的所有組合。依此類推,直到找出所有的組合為止,實(shí)現(xiàn)代碼如下:
"""
方法功能:求和為sums的所有整數(shù)組合
輸入?yún)?shù):sums正整數(shù),result存儲組合結(jié)果,count記錄組合中數(shù)字的個(gè)數(shù)
"""
defgetAllCombination(sums,result,count):
ifsums<0:
return
#數(shù)字的組合滿足和為sums的條件,打印出所有組合
ifsums==0:
prrnt"滿足條件的組合:".
i=0
whilei<count:
printresult[i],
i+=1
print'\n'
return
#打印debug信息,為了便于理解
print"----當(dāng)前組合:",
i=0
whilei<count:
printstr(result[i]),
i+=1
print"----"
#確定組合中下一個(gè)取值
i=(1ifcount==0elseresult[count-1])
print"---"+"i="+str(i)+"count="+str(count)+"---"#打印debug信息,為了便于理解
whilei<=sums:
result[count]=i
count+=1
getAllCombination(sums-i,result,count)#求和為sums-i的組合
count-=1#遞歸完成后,去掉最后一個(gè)組合的數(shù)字
i+=1#找下一個(gè)數(shù)字作為組合中的數(shù)字
#方法功能:找出和為n的所有整數(shù)的組合
defshowAllCombination(n):
ifn<1:
print"參數(shù)不滿足要求"
return
result=[None]*n#存儲和為n的組合方式
getAllCombination(n,result,0)
if__name__=="__main__":
showAllCombination(4)
程序的運(yùn)行結(jié)果為:
----當(dāng)前組合:----
---i=1count=0---
----當(dāng)前組合:1----
---i=1count=1---
----當(dāng)前組合:11----
---i=1count=2---
----當(dāng)前組合:111----
---i=1count=3---
滿足條件的組合:1111
滿足條件的組合:112
----當(dāng)前組合:12----
---i=2count=2---
滿足條件的組合:13
----當(dāng)前組合:2----
---i=2count=1---
滿足條件的組合:22
----當(dāng)前組合:3----
----i=3count=1---
滿足條件的組合:4
運(yùn)行結(jié)果分析:
從上面運(yùn)行結(jié)果可以看出,滿足條件的組合為:{1,1,1,1},{1,1,2},{1,3},{2,2},{4},其他的為調(diào)試信息。從打印出的信息可以看出:在求和為4的組合中,第一步選擇了1;然后求3(4-1)的組合也選了1,求2(3-1)的組合的第一步也選擇了1,依次類推,找出第一個(gè)組合為{1,1,1,1}。然后通過count-和i+找出最后兩個(gè)數(shù)字1與1的另外一種組合2,最后三個(gè)數(shù)字的另外一種組合3;接下來用同樣的方法分別選擇2,3作為組合的第一個(gè)數(shù)字,就可以得到以上結(jié)果。
代碼i=(count==0?1:result[count-1]);用來保證:組合中的下一個(gè)數(shù)字一定不會小于前一個(gè)數(shù)字,從而保證了組合的遞增性。如果不要求遞增(例如把{1,1,2}和{2,1,1}看作兩種組合),那么把上面一行代碼改成i=1即可。)解析:[考點(diǎn)]如何求正整數(shù)n所有可能的整數(shù)組合。4.
有一個(gè)函數(shù)func1能返回0和1兩個(gè)值,返回0和1的概率都是1/2,問怎么利用這個(gè)函數(shù)得到另一個(gè)函數(shù)func2,使func2也只能返回0和1,且返回0的概率為1/4,返回1的概率為3/4。
(分?jǐn)?shù):14.00)__________________________________________________________________________________________
正確答案:(func1得到1與0的概率都為1/2。因此,可以調(diào)用兩次func1,分別生成兩個(gè)值a1與a2,用這兩個(gè)數(shù)組成一個(gè)二進(jìn)制a2a1,它的取值的可能性為00,01,10,11,并且得到每個(gè)值的概率都為(1/2)*(1/2)=1/4,因此,如果得到的結(jié)果為00,那么返回0(概率為1/4),其他情況返回1(概率為3/4)。實(shí)現(xiàn)代碼如下:
importrandom
#返回0和1的概率都為1/2
deffunc1():
returnint(round(random.random())
#返回0的概率為1/4,返回1的概率為3/4
deffunc2():
a1=func1()
a2=func1()
tmp=a1
tmp1=(a2<<1)
iftmp==0:
return0
else:
return1
if__name__=="__main__":
i=0
whilei<16:
printfunc2(),
i+=1
print'\n'
i=0
whilei<16:
printfunc2(),
i+=1
程序的運(yùn)行結(jié)果為:
1110110110111101
1111111111000010
由于結(jié)果是隨機(jī)的,調(diào)用的次數(shù)越大,返回的結(jié)果就越接近1/4與3/4。)解析:[考點(diǎn)]如何用一個(gè)隨機(jī)函數(shù)得到另外一個(gè)隨機(jī)函數(shù)。5.
隨機(jī)地從大小為n的數(shù)組中選取m個(gè)整數(shù),要求每個(gè)元素被選中的概率相等。
(分?jǐn)?shù):14.00)__________________________________________________________________________________________
正確答案:(從n個(gè)數(shù)中隨機(jī)選出一個(gè)數(shù)的概率為1/n,然后在剩下的n-1個(gè)數(shù)中再隨機(jī)找出一個(gè)數(shù)的概率也為1/n(第一次沒選中這個(gè)數(shù)的概率為(n-1)/n,第二次選中這個(gè)數(shù)的概率為1/(n-1),因此,隨機(jī)選出第二個(gè)數(shù)的概率為((n-1)/n)*(1/(n-1))=1/n),依次類推,在剩下的k個(gè)數(shù)中隨機(jī)選出一個(gè)元素的概率都為1/n。因此,這種方法的思路為:首先從有n個(gè)元素的數(shù)組中隨機(jī)選出一個(gè)元素,然后把這個(gè)選中的數(shù)字與數(shù)組第一個(gè)元素交換,接著從數(shù)組后面的n-1個(gè)數(shù)字中隨機(jī)選出1個(gè)數(shù)字與數(shù)組第二個(gè)元素交換,依次類推,直到選出m個(gè)數(shù)字為止,數(shù)組前m個(gè)數(shù)字就是隨機(jī)選出來的m個(gè)數(shù)字,且它們被選中的概率相等。實(shí)現(xiàn)代碼如下:
importrandom
defgetRandomM(a,n,m):
ifa==Noneorn<=0orn<m:
print"參數(shù)不合理"
return
i=0
whilei<m:
j=random.randint(i,n-1)#//獲取i到n-1間的隨機(jī)數(shù)
#隨機(jī)選出的元素放到數(shù)組的前面
tmp=a[i]
a[i]=a[j]
a[j]=tmp
i+=1
if__name__=="__main__":
a=[1,2,3,4,5,6,7,8,9,10]
n=10
m=6
getRandomM(a,n,m)
i=0
whilei<m:
printa[i],
i+=1
程序的運(yùn)行結(jié)果為:
1
8
9
7
2
4
算法性能分析:
這種方法的時(shí)間復(fù)雜度為O(m)。)解析:[考點(diǎn)]如何等概率地從大小為n的數(shù)組中選取m個(gè)整數(shù)。6.
求出用1,2,5這三個(gè)數(shù)不同個(gè)數(shù)組合的和為100的組合個(gè)數(shù)。為了更好地理解題目的意思,下面給出幾組可能的組合:100個(gè)1,0個(gè)2和0個(gè)5,它們的和為100;50個(gè)1,25個(gè)2,0個(gè)5的和也是100;50個(gè)1,20個(gè)2,2個(gè)5的和也為100。
(分?jǐn)?shù):14.00)__________________________________________________________________________________________
正確答案:(方法一:蠻力法
最簡單的方法就是對所有的組合進(jìn)行嘗試,然后判斷組合的結(jié)果是否滿足和為100,這些組合有如下限制:1的個(gè)數(shù)最多為100個(gè),2的個(gè)數(shù)最多為50個(gè),5的個(gè)數(shù)最多為20個(gè)。實(shí)現(xiàn)思路為:遍歷所有可能的組合l的個(gè)數(shù)x(0<=x<=100),2的個(gè)數(shù)y(0=<y<=50),5的個(gè)數(shù)z(0<=z<=20),判斷x+2y+5z是否等于100,如果相等,那么滿足條件,實(shí)現(xiàn)代碼如下:
defcombinationCount(n):
count=0
num1=n#1最多的個(gè)數(shù)
num2=n/2#2最多的個(gè)數(shù)
num5=n/5#5最多的個(gè)數(shù)
x=0
whilex<==num1:
y=0
whiley<=num2:
z=0
whilez<=num5:
ifx+2*y+5*z==n:#滿足條件
count+=1
z+=1
y+=1
x+=1
returncount
if__name__=="__main__":
printcombinationCount(100)
程序的運(yùn)行結(jié)果為:
541
算法性能分析:
這種方法循環(huán)的次數(shù)為101*51*21。
方法二:數(shù)字規(guī)律法
針對這種數(shù)學(xué)公式的運(yùn)算,一般都可以通過找出運(yùn)算的規(guī)律進(jìn)而簡化運(yùn)算的過程,對于本題而言,對x+2y+5z=100進(jìn)行變換可以得到x+5z=100-2y。從這個(gè)表達(dá)式可以看出,x+5z是偶數(shù)且x+5z<=100。因此,求滿足x+2y+5z=100組合的個(gè)數(shù)就可以轉(zhuǎn)換為求滿足“x+5z是偶數(shù)且x+5z<=100”的個(gè)數(shù)??梢酝ㄟ^對z的所有可能的取值(0<=z<=20)進(jìn)行遍歷從而計(jì)算滿足條件的x的值。
當(dāng)z=0時(shí),x的取值為0,2,4,…,100(100以內(nèi)所有的偶數(shù)),個(gè)數(shù)為(100+2)/2
當(dāng)z=1時(shí),x的取值為1,3,5,…,95(95以內(nèi)所有的奇數(shù)),個(gè)數(shù)為(95+2)/2
當(dāng)z=2時(shí),x的取值為0,2,4,…,90(90以內(nèi)所有的偶數(shù)),個(gè)數(shù)為(90+2)/2
當(dāng)z=3時(shí),x的取值為1,3,5,…,85(85以內(nèi)所有的奇數(shù)),個(gè)數(shù)為(85+2)/2
當(dāng)z-19時(shí),x的取值為5,3,1(5以內(nèi)所有的奇數(shù)),個(gè)數(shù)為(5+2)/2
當(dāng)z=20時(shí),x的取值為0(0以內(nèi)所有的偶數(shù)),個(gè)數(shù)為(0+2)/2
根據(jù)這個(gè)思路,實(shí)現(xiàn)代碼如下:
defcombinationCount(n):
count=0
m=0
whilem<=n:
count+=(m+2)/2
m+=5
returncount
算法性能分析:
這種方法循環(huán)的次數(shù)為21。)解析:[考點(diǎn)]如何組合1,2,5這三個(gè)數(shù)使其和為100。7.
100個(gè)燈泡排成一排,第一輪將所有燈泡打開;第二輪每隔一個(gè)燈泡關(guān)掉一個(gè),即排在偶數(shù)的燈泡被關(guān)掉,第三輪每隔兩個(gè)燈泡,將開著的燈泡關(guān)掉,關(guān)掉的燈泡打開。依次類推,第100輪結(jié)束的時(shí)候,還有幾盞燈泡亮著?
(分?jǐn)?shù):16.00)_____________________
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年教育機(jī)構(gòu)校長聘用合同書3篇
- 2024版勞務(wù)派遣就業(yè)合同范本
- 二零二四南京個(gè)人租賃房屋租賃合同租賃物交付驗(yàn)收合同3篇
- 年度Β-內(nèi)酰胺類抗菌藥物產(chǎn)業(yè)分析報(bào)告
- 年度高檔生物顯微鏡競爭策略分析報(bào)告
- 年度大孔燒結(jié)空心磚競爭策略分析報(bào)告
- 2025年西瓜種植與農(nóng)業(yè)科技園區(qū)建設(shè)合作合同范本3篇
- 金屬材料及工藝技術(shù)創(chuàng)新研究報(bào)告
- 2025年度淋浴房淋浴房頂安裝合同4篇
- 二零二四年危化品押運(yùn)員安全管理責(zé)任書與考核合同3篇
- 寒潮雨雪應(yīng)急預(yù)案范文(2篇)
- DB33T 2570-2023 營商環(huán)境無感監(jiān)測規(guī)范 指標(biāo)體系
- 上海市2024年中考英語試題及答案
- 房屋市政工程生產(chǎn)安全重大事故隱患判定標(biāo)準(zhǔn)(2024版)宣傳海報(bào)
- 垃圾車駕駛員聘用合同
- 2025年道路運(yùn)輸企業(yè)客運(yùn)駕駛員安全教育培訓(xùn)計(jì)劃
- 南京工業(yè)大學(xué)浦江學(xué)院《線性代數(shù)(理工)》2022-2023學(xué)年第一學(xué)期期末試卷
- 2024版機(jī)床維護(hù)保養(yǎng)服務(wù)合同3篇
- 《論拒不執(zhí)行判決、裁定罪“執(zhí)行能力”之認(rèn)定》
- 工程融資分紅合同范例
- 2024國家安全員資格考試題庫加解析答案
評論
0/150
提交評論