题目描述
有一个6*6的棋盘,每个棋盘上都有一个数值,现在又一个起始位置和终止位置,请找出一个从起始位置到终止位置代价最小的路径: 1、只能沿上下左右四个方向移动 2、总代价是没走一步的代价之和 3、每步(从a,b到c,d)的代价是c,d上的值与其在a,b上的状态的乘积 4、初始状态为1 每走一步,状态按如下公式变化:(走这步的代价%4)+1。
输入描述:
每组数据一开始为6*6的矩阵,矩阵的值为大于等于1小于等于10的值,然后四个整数表示起始坐标和终止坐标。
输出描述:
输出最小代价。
示例1
输入
复制
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 5 5
输出
复制
23
有俩种方法,第一种直接广搜,第二种启发式搜索,优先搜索代价小的路径。不过最后比较搜索的节点变化不大,就当练习使用优先级队列和A*算法了。
广搜:
import Queue class state(): def __init__(self,row,col,s): self.row=row self.col=col self.s=s def get_input(): chart=[] for i in range(6): num=raw_input() tem=[] for each in num.split(" "): tem.append(int(each)) chart.append(tem) num=raw_input().split(" ") start_r,start_c,end_r,end_c=int(num[0]),int(num[1]),int(num[2]),int(num[3]) return chart,start_r,start_c,end_r,end_c def min_cost(): #chart, start_r, start_c, end_r, end_c=get_input() chart=[] for i in range(6): tem=[] for j in range(6): tem.append(1) chart.append(tem) start_r, start_c, end_r, end_c=0,0,5,5 each_state=[] for i in range(6): tem0=[] for j in range(6): tem0.append([-1]*5) each_state.append(tem0) q=Queue.Queue() direction=[[0,1],[1,0],[-1,0],[0,-1]] start_node=state(start_r,start_c,1) each_state[start_node.row][start_node.col][start_node.s]=0 q.put(start_node) time=0 while not q.empty(): tem_node=q.get() time+=1 #print tem_node.row,tem_node.col,tem_node.s,each_state[tem_node.row][tem_node.col][tem_node.s] for each in direction: new_row,new_col=tem_node.row+each[0],tem_node.col+each[1] if new_row>=0 and new_row<6 and new_col>=0 and new_col<6: cost=tem_node.s*chart[new_row][new_col] new_cost=cost+each_state[tem_node.row][tem_node.col][tem_node.s] new_s = cost%4 + 1 if each_state[new_row][new_col][new_s]<0 or new_cost<each_state[new_row][new_col][new_s]: new_s=tem_node.s*chart[new_row][new_col]%4+1 new_node=state(new_row,new_col,new_s) q.put(new_node) each_state[new_row][new_col][new_s]=new_cost min_c=-1 for each in each_state[end_r][end_c]: if each>=0 and (min_c==-1 or (min_c>=0 and each<min_c)): min_c=each print min_c print time min_cost()
A*:
import Queue class state(): def __init__(self,row,col,s,cost): self.row=row self.col=col self.s=s self.cost=cost def __cmp__(self, other): return cmp(self.cost,other.cost) def get_input(): chart=[] for i in range(6): num=raw_input() tem=[] for each in num.split(" "): tem.append(int(each)) chart.append(tem) num=raw_input().split(" ") start_r,start_c,end_r,end_c=int(num[0]),int(num[1]),int(num[2]),int(num[3]) return chart,start_r,start_c,end_r,end_c def min_cost(): #chart, start_r, start_c, end_r, end_c=get_input() chart=[] for i in range(6): tem=[] for j in range(6): tem.append(1) chart.append(tem) start_r, start_c, end_r, end_c=0,0,5,5 each_cost=[] for i in range(6): tem0=[] for j in range(6): tem0.append([-1]*5) each_cost.append(tem0) q=Queue.PriorityQueue() direction=[[0,1],[1,0],[-1,0],[0,-1]] start_node=state(start_r,start_c,1,0) each_cost[start_node.row][start_node.col][start_node.s]=0 q.put(start_node) minimal_cost=-1 time=0 while not q.empty(): current_node=q.get() time+=1 if (current_node.row == end_r and current_node.col == end_c) and (minimal_cost < 0 or current_node.cost < minimal_cost): minimal_cost = current_node.cost #print current_node.row,current_node.col,current_node.s,current_node.cost for each in direction: new_row, new_col = current_node.row + each[0], current_node.col + each[1] if new_row >= 0 and new_row < 6 and new_col >= 0 and new_col < 6: cost = current_node.s * chart[new_row][new_col] new_cost = cost + each_cost[current_node.row][current_node.col][current_node.s] new_s = cost % 4 + 1 if minimal_cost<0 or (minimal_cost>=0 and new_cost<minimal_cost): if each_cost[new_row][new_col][new_s] < 0 or new_cost < each_cost[new_row][new_col][new_s]: new_node = state(new_row, new_col, new_s,new_cost) q.put(new_node) each_cost[new_row][new_col][new_s] = new_cost print minimal_cost print time min_cost()