【计蒜客】基础算法入门之深度搜索

很想写一个很好的文章引子,但是囿于语文水平有限,写不出什么好东西来,干脆就随便写点东西吧。之前写的文章都是关于爬虫的,爬虫虽好,但是写来写去就是那些东西,是时候学习点新东西了!现在自己很缺关于算法的知识,于是就上计蒜客学习了基础算法入门,但是苦于它教学用的是C++,而我大一学过C++,现在早就忘光了。于是我将写几篇系列文章,将计蒜客上面的C++算法改写成Python。

这是第二篇文章《深度搜索》

以下文字摘自计蒜客

问题背景:


蒜头君一天闲来无事和小萌一起玩游戏,游戏的内容是这样的:他们不知道从哪里找到了N根不同长度的木棍,看谁能猜出这些木棍一共能拼出多少个不同的不等边三角形。注意在拼三角形的时候一定要用上所有的N根木棍哦。不同的定义是至少有一条边的长度不相同;不等边的定义是三条边都不相等。

蒜头君和小萌数学都不太好,每个人都猜到一个数字后才意识到他们并不知道正确答案。于是他们来请教聪明的你,能帮他们算出正确答案么?

输入格式:

第一行为数据组数T,(1<=T<=15)。

接下来每组数据占两行,第一行为木棍的数量N(1<=N<=15)

第二行有N个正整数li (1<=li<100),表示N个木棍的长度。保证每个长度都不相同。

输出格式:每组数据输出一个非负整数,表示能组成的不同的三角形个数。

样例输入:

1
3
2 3 4
样例输出:
1


C++的注释看这篇文章:

《计蒜客课程系列:统计三角形(DFS+哈希状态存储标记)》

这篇文章已经注释的很清楚了。


然后是我改写的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改写的算法输入却是:

1
1
1
1
1
1
因为它把 2 3 4 、 2 4 3 、 3 4 2 、 3 2 4 、 4 2 3 、 4 3 2当成6种不同的三角形处理。。
为了解决这个问题,我就把三边之积来储存三角形方法了。。


主要是上面两个问题,然后就贴出代码:

<span style="font-family:Arial;font-size:18px;">#-*-coding=utf-8-*-

h=[];n=0;l=[];count=0
#定义h长度。。。。
for i in xrange(10000):
	h.append(False)

f=open('triangle.txt')
	
#判断是否为三角形
def is_triangle(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_triangle(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):
			h.append(False)
		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'</span>



读取的文件triangle.txt:

<span style="font-size:18px;">2
4
2 3 4 5
3
2 3 4</span>

输出
<span style="font-size:18px;">1
2

1</span>




你可能感兴趣的:(算法,python,深度搜索)