從一個22網格的左上角開始,有6條(不容許往回走)通往右下角的路。php
對於2020的網格,這樣的路有多少條?python
class NetGame(): """丟入一個n X n格的網絡 說明: x:橫座標, y:縱座標 如(x,y)表示 數組net[y][x] """ def __init__(self,cell=None): # 初始化網絡 ,從左上角開始,到右下角,只能向右/向下方向前進 if not cell:raise KeyError self.net = [[0 for i in range(cell+1)] for j in range(cell+1)] # 創建二維座標網絡 self.length = cell+1 # 長度 def check_next(self,x,y): """檢測下一步能夠向哪方向走 {'down':True,'right':False} """ arrow = {'down':True,'right':True} if y >= self.length-1: arrow['down'] = False if x >= self.length-1: arrow['right'] = False return arrow def go_down(self,x,y): # 傳入向下走一步, 返回座標 return (x,y+1) def go_right(self,x,y): # 向右走一步 return (x+1,y) def check_end(self,x,y): """檢查座標是否已經到終點""" if (x,y) == (self.length-1, self.length-1): return True return False def run_from_xy(self,x,y ): """從當前座標(x,y) 開始向座標(n-1,n-1)終點行走,返回可能的路線. """ path_list = [(x,y)] # 收集途經座標,第一個是起點座標 def running(path_list): x,y = path_list[-1] # 最後一個座標 if self.check_end(x,y): yield path_list arrow = self.check_next(x,y) for direction,TF in arrow.iteritems(): if TF: # 哪一個方向能夠走, 設置爲1 go_func = eval('self.go_%s' % direction) # 套入go_down,go_right new_x,new_y = go_func(x,y) # 取得下一步的座標 在這裏 x,y=go_func(x,y) 吃了大虧!! path_list_new = path_list[:] path_list_new.append((new_x,new_y)) # 將座標加入路徑列表 for i in running(path_list_new): yield i return running(path_list) def run(self): """從(0,0)座標開始行走,返回通過座標的列表""" return self.run_from_xy(0,0) @property def count(self): """列出全部路線之和,從(0,0)開始""" count_cnt = 0 for ele in self.run(): count_cnt += 1 return count_cnt def list_array(self): """列出全部線路的二維數組""" import copy for coordinate in self.run(): # 返回座標列表 net = copy.deepcopy(self.net) for x,y in coordinate: net[y][x] = 1 yield net
彷佛能夠作成機器人走走的算法. 算法
首先驗證一下題目數組
import time t1 = time.time() net = NetGame(cell=2) print "通過的線路座標:" cnt = 0 for e in net.run(): print e cnt+=1 print "路線數:",cnt t2 = time.time() print "共用時間:",t2-t1 print "全部的線路二維座標:" for i in net.list_array(): print i
通過的線路座標:網絡
[(0, 0), (0, 1), (0, 2), (1, 2), (2, 2)]app
[(0, 0), (0, 1), (1, 1), (1, 2), (2, 2)]spa
[(0, 0), (0, 1), (1, 1), (2, 1), (2, 2)].net
[(0, 0), (1, 0), (1, 1), (1, 2), (2, 2)]code
[(0, 0), (1, 0), (1, 1), (2, 1), (2, 2)]orm
[(0, 0), (1, 0), (2, 0), (2, 1), (2, 2)]
路線數: 6
共用時間: 0.0
全部的線路二維座標:
[[1, 0, 0], [1, 0, 0], [1, 1, 1]]
[[1, 0, 0], [1, 1, 0], [0, 1, 1]]
[[1, 0, 0], [1, 1, 1], [0, 0, 1]]
[[1, 1, 0], [0, 1, 0], [0, 1, 1]]
[[1, 1, 0], [0, 1, 1], [0, 0, 1]]
[[1, 1, 1], [0, 0, 1], [0, 0, 1]]
若是改成10格呢j, 線路列表太多,不輸出了.
import time t1 = time.time() net = NetGame(cell=10) print "路線數:",net.count t2 = time.time() print "共用時間:",t2-t1
路線數: 184756
共用時間: 10.503000021
若是是20格呢? 所用時間半個小時也運行不完. 算法不太懂. 先略過
貼上一個很吊的算法:
cache = {} def countRoutes(m,n): if m==0 or n==0: return 1 if (m,n) in cache: return cache[(m,n)] cache[(m,n)] = countRoutes(m,n-1) + countRoutes(m-1,n) return cache[(m,n)] import time t1 = time.time() print countRoutes(20,20) print time.time()-t1
137846528820
0.0
時間爲0 !!!!!!