很想寫乙個很好的文章引子,但是囿於語文水平有限,寫不出什麼好東西來,乾脆就隨便寫點東西吧。之前寫的文章都是關於爬蟲的,爬蟲雖好,但是寫來寫去就是那些東西,是時候學習點新東西了!現在自己很缺關於演算法的知識,於是就上計蒜客學習了基礎演算法入門,但是苦於它教學用的是c++,而我大一學過c++,現在早就忘光了。於是我將寫幾篇系列文章,將計蒜客上面的c++演算法改寫成python。
這是第二篇文章《深度搜尋》
以下文字摘自計蒜客
問題背景:
蒜頭君一天閒來無事和小萌一起玩遊戲,遊戲的內容是這樣的:他們不知道從**找到了n根不同長度的木棍,看誰能猜出這些木棍一共能拼出多少個不同的不等邊三角形。注意在拼三角形的時候一定要用上所有的n根木棍哦。不同的定義是至少有一條邊的長度不相同;不等邊的定義是三條邊都不相等。
蒜頭君和小萌數學都不太好,每個人都猜到乙個數字後才意識到他們並不知道正確答案。於是他們來請教聰明的你,能幫他們算出正確答案麼?
輸入格式:
第一行為資料組數t,(1<=t<=15)。
接下來每組資料佔兩行,第一行為木棍的數量n(1<=n<=15)
第二行有n個正整數li (1<=li<100),表示n個木棍的長度。保證每個長度都不相同。
輸出格式:每組資料輸出乙個非負整數,表示能組成的不同的三角形個數。
樣例輸入:
1樣例輸出:32 3 4
1
c++的注釋看這篇文章:
這篇文章已經注釋的很清楚了。
然後是我改寫的python**。
改寫的**有點問題,主要是:
1、題目要求在最後輸出的時候只輸出乙個結果,但是我這個沒辦法做到,就只能得到乙個結果輸出結果。比如有4個木棒長度分別是:2 3 4 5,問他們能組合出幾種三角形。結果是:5 4 5、6 3 5兩種結果,輸出就應該是:
2
但是我改寫成python後就是輸出:
1
2
2、不知道是語言之間的不同還是我不太理解雜湊儲存的原理,提示給出判斷乙個組合是否出現過得方式是這樣的:(摘自計蒜客)
我們定義乙個陣列h,用來判斷乙個三角形的方案是否已經存在過。
因為三條邊的總長度是確定的,所以只要確定了兩條邊的長度就能知道第三條邊的長度了。那麼我們將三角形儲存為第一條邊的長度*100+第二條邊的長度。
在c++中這樣是沒問題,但是我改寫成python的時候就不行了。以2、3、4三個木棍來說,本來輸出應該只是
1
但是按照上面的方法,我用python改寫的演算法輸入卻是:
111
111
因為它把 2 3 4 、 2 4 3 、 3 4 2 、 3 2 4 、 4 2 3 、 4 3 2當成6種不同的三角形處理。。
為了解決這個問題,我就把三邊之積來儲存三角形方法了。。
主要是上面兩個問題,然後就貼出**:
#-*-coding=utf-8-*-
h=;n=0;l=;count=0
#定義h長度。。。。
for i in xrange(10000):
f=open('********.txt')
#判斷是否為三角形
def is_********(a,b,c):
global h
if (not h[a*b*c])&(a>0)&(b>0)&(c>0)&(a+b>c)&(a+c>b)&(b+c>a):#表示此方案沒有出現過、三條邊都要大於0、兩邊之和大於第三邊
h[a*b*c]=true
return true
else:
return false
'''接下來就是深搜,按照比較自然的思路,就是列舉每根木棍放到三堆裡的哪一堆中,直到把所有木棍都放到了三堆之一中,再去判斷三對內所有木棍的長度和作為三角形的邊長是否合法即可。所以,我們搜尋的時候要儲存列舉到第幾根木棍,以及三堆木棍當前的總長度。*/
def dfs(index,l,n,a,b,c):#6個引數代表索引、長棍的長度(這是乙個list)、長棍的數目,三條邊
global count
if index==n:
if is_********(a,b,c):
count+=1
print count
else:
dfs(index+1,l,n,a+l[index],b,c)
dfs(index+1,l,n,a,b+l[index],c)
dfs(index+1,l,n,a,b,c+l[index])
if __name__=='__main__':
t=int(f.readline())
while t>0:
t-=1
h=;n=0;l=;count=0
#定義h長度。。。。
for i in xrange(10000):
m=int(f.readline())
dat=f.readline()
l=[int(s) for s in dat.strip().split()]
dfs(0,l,m,0,0,0)
print '\n'
讀取的檔案********.txt:
2
42 3 4 5
32 3 4
輸出
1
21
計蒜客深度優先搜尋基礎題目 走迷宮
dfs 和遞迴的區別是,dfs 是一種演算法,注重的是思想,而遞迴是程式語言的一種寫法。我們通過遞迴的寫法來實現 dfs 下面我們通過乙個實際問題來理解 dfs 到底幹了什麼。s t其中 s 表示起點,t 表示終點,表示牆壁,表示平地。你需要從 s 出發走到 t 每次只能上下左右走動,並且不能走出地...
計蒜客 程式設計競賽入門
蒜頭的數學實在是太差了,於是老師把他關到小黑屋讓他閉門修煉。老師跟他一張紙,上面一排寫著1,2,3 n這n個數,中間用空白分隔。老師讓他在空白處填上加號或者減號。他讓蒜頭君求出一共有多少種加運算子的方法使得整個表示式的值為0,並輸出所有的方案。比如n 7時,1 2 3 4 5 6 7排成一排,一種插...
計蒜客 程式設計競賽入門
蒜頭君前幾天把最心愛的小麥手機摔壞了,新手機又要好幾天才能到貨,於是蒜頭君不得暫時用它珍藏已久的諾雞鴨非智慧型手機了。手機的儲存空間非常小,以至於未接來電 已接來電和已撥 都只能各自儲存最近的10條記錄。蒜頭買了手機以後的未接來電 已接來電和已撥 記錄全部給出。機智的蒜頭能夠猜到這個手機使用了迴圈佇...