您的位置:首页 > 编程语言

算法谜题——夜过吊桥代码实现

2014-06-12 22:32 337 查看
问题描述:四个人打算过一座吊桥,开始时他们都位于该桥的一侧。天很黑,四个人手里只有一个手电筒。该桥一次最多只能同时过两个人,无论是一个人还是两个人过桥,都需要携带手电筒看路。而且手电筒只能通过人携带过桥的方式传递。第一个人过桥需要1分钟时间,第二个人过桥需要2分钟,第三个人需要5分钟,第四个需要10分钟。由于速度不同,两个人一起过桥的话,速度以慢的人为准。例如,如果第一个人和第四个人一起过桥,两个人到达对岸需要10分钟,如果让4号走回来返还手电筒,则还需要10分钟。这一共就花了20分钟。问他们四人能在17分钟内过桥吗?

想法一:用贪心算法的思想,每次让第一个人分别与其他人一起过桥,然后第一个人再回来送手电筒,这样,总共花费的时间是(2+1)+(5+1)+(10)=19分钟

想法二:把两次过桥和送手电筒作为一个回合,考虑下面两种方式的时间:

(假设X,Y为最慢和次慢的过桥者,x,y为最快和次快的过桥者。)
A:用最快的X陪同最慢和次慢的x,y过桥。
也就是第一步x,X过桥,x回头(花费x+X分钟);
第二步x,Y过桥,x回头(花费Y+x分钟);
这种方式一次花掉2*x+X+Y分钟。
B:用最快和次快的x,y陪同最慢和次慢的X,Y过桥。
也就是第一步x,y过桥,x回头(花费x+y分钟);
第二步X,Y过桥,y回头(花费X+y分钟);
这种方式一次花掉x+2*y+X分钟。
显然上面的两种方法,当2*x+X+Y<x+2*y+X的时候,选A否则选B过桥。
上述方法用python实现代码如下:
def function1(left,right,sum):
		left.sort()
		print '%d ,%d cross the bridge' % (left[0],left[1])
		x=left.pop(0)
		y=left.pop(0)
		right.extend([x,y])
		right.sort()
		sum+=max(x,y)
		print '%d go back to the left' %right[0]
		z=right.pop(0)
		left.extend([z])
		left.sort()
		sum+=z
		print '%d ,%d cross the bridge' % (left[len(left)-1],len(left)-2)
		x=left.pop(len(left)-1)
		y=left.pop(len(left)-1)
		right.extend([x,y])
		right.sort()
		sum+=max(x,y)	
		if len(left)!=0:	
				print '%d go back to the left' %right[0]
				z=right.pop(0)
				left.extend([z])
				sum+=z
		return sum		
		
def function2(left,right,sum):
		left.sort()
		print '%d ,%d cross the bridge' % (left[0],left[len(left)-1])
		x=left.pop(0)
		y=left.pop(len(left)-1)
		right.extend([x,y])
		right.sort()
		sum+=y
		print '%d go back to the left' %right[0]
		z=right.pop(0)
		left.extend([z])
		left.sort()
		sum+=z
		print '%d ,%d cross the bridge' % (left[0],left[len(left)-1])
		x=left.pop(0)
		y=left.pop(len(left)-1)
		right.extend([x,y])
		right.sort()
		sum+=y
		if len(left)!=0:
				print '%d go back to the left' %right[0]
				z=right.pop(0)
				left.extend([z])
				sum+=z
		return sum
		

def cross_bridge(left):
		sum=0
		right=[]
		left.sort()
		min1=left[0]
		min2=left[1]
		max1=left[len(left)-1]
		max2=left[len(left)-2]
		while len(left)>2:
				if 2*min1+max1+max2<min1+2*min2+max1:
						sum=function2(left,right,sum)
						#print sum
				else:
						sum=function1(left,right,sum)
						#print sum
		print '%d ,%d cross the bridge' % (left[0],left[1])
		sum+=left[1]
		print 'All time used is %d' %sum
		
def max(a,b):
		if a>b:
				return a
		else:
				return b		
				
left=[1,2,5,10]
cross_bridge(left)


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: