Project Euler 83:Path sum: four ways 路径和:4个方向
2015-11-23 21:54
357 查看
Path sum: four ways
NOTE: This problem is a significantly more challenging version of Problem 81.
In the 5 by 5 matrix below, the minimal path sum from the top left to the bottom right, by moving left, right, up, and down, is indicated in bold red and is equal to 2297.
Find the minimal path sum, in matrix.txt (right click and “Save Link/Target As…”), a 31K text file containing a 80 by 80 matrix, from the top left to the bottom right by moving left, right, up, and down.
路径和:四个方向
注意:这是第81题的一个极具挑战性的版本。
在如下的5乘5矩阵中,从左上角到右下角任意地向上、向下、向左或向右移动的最小路径和为2297,由标注红色的路径给出。
在这个31K的文本文件matrix.txt (右击并选择“目标另存为……”)中包含了一个80乘80的矩阵,求出从左上角到右下角任意地向上、向下、向左或向右移动的最小路径和。
解题
表示很复杂,这个应该用到图,dijkstra算法可解。
参考解题论坛中的程序,也就是dijkstra算法,只是用Python实现起来,比较简单。
实现思路:
1.当前节点(0,0)开始,在临近节点,寻找最短路径
2.是最短路径的节点位置保存
3,根据2中保存的节点,再找其到临近节点的最短路径
Python
Java
Java Code
NOTE: This problem is a significantly more challenging version of Problem 81.
In the 5 by 5 matrix below, the minimal path sum from the top left to the bottom right, by moving left, right, up, and down, is indicated in bold red and is equal to 2297.
131 | 673 | 234 | 103 | 18 |
201 | 96 | 342 | 965 | 150 |
630 | 803 | 746 | 422 | 111 |
537 | 699 | 497 | 121 | 956 |
805 | 732 | 524 | 37 | 331 |
路径和:四个方向
注意:这是第81题的一个极具挑战性的版本。
在如下的5乘5矩阵中,从左上角到右下角任意地向上、向下、向左或向右移动的最小路径和为2297,由标注红色的路径给出。
131 | 673 | 234 | 103 | 18 |
201 | 96 | 342 | 965 | 150 |
630 | 803 | 746 | 422 | 111 |
537 | 699 | 497 | 121 | 956 |
805 | 732 | 524 | 37 | 331 |
解题
表示很复杂,这个应该用到图,dijkstra算法可解。
参考解题论坛中的程序,也就是dijkstra算法,只是用Python实现起来,比较简单。
实现思路:
1.当前节点(0,0)开始,在临近节点,寻找最短路径
2.是最短路径的节点位置保存
3,根据2中保存的节点,再找其到临近节点的最短路径
Python
import time def readData(filename): fl = open(filename) data =[] for row in fl: row = row.split(',') line = [int(i) for i in row] data.append(line) fl.close() return data def next_steps(pos): (j,i) = pos if i+1<size: right = minnum[j,i] + data[j][i+1] if right< minnum[j,i+1]: minnum[j,i+1] = right next_list.append((j,i+1)) if j+1< size: down = minnum[j,i] + data[j+1][i] if down < minnum[j+1,i]: minnum[j+1,i] = down next_list.append((j+1,i)) if i-1 > -1: left = minnum[j,i] + data[j][i-1] if left < minnum[j,i-1]: minnum[j,i-1] = left next_list.append((j,i-1)) if j-1 > -1: up = minnum[j,i] + data[j-1][i] if up < minnum[j-1,i]: minnum[j-1,i] = up next_list.append((j-1,i)) t0 = time.time() filename = 'E:/java/projecteuler/src/Level3/p083_matrix.txt' data = readData(filename) size = 80 infinity = 10**10 minnum = {} for i in range(0,size): for j in range(0,size): minnum[j,i] = infinity next_list = [] minnum[0,0] = data[0][0] test = [(0,0)] while test!=[]: next_list = [] for el in test: next_steps(el) test = next_list print minnum[size-1,size-1] t1 = time.time() print "running time=",(t1-t0),"s" # 425185 # running time= 0.112999916077 s
Java
package Level3; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; public class PE083{ static int[][] grid; static void run() throws IOException{ String filename = "src/Level3/p083_matrix.txt"; String lineString = ""; ArrayList<String> listData = new ArrayList<String>(); BufferedReader data = new BufferedReader(new FileReader(filename)); while((lineString = data.readLine())!= null){ listData.add(lineString); } // 分配大小空间的 定义的grid 没有定义大小 assignArray(listData.size()); // 按照行添加到数组grid中 for(int index = 0,row_counter=0;index <=listData.size() - 1;++index,row_counter++){ populateArray(listData.get(index),row_counter); } int result = minPath(grid,0,0,80-1,80-1); System.out.println(result); } // matrix[a][b] to matrix[c][d] 的最小值 public static int minPath(int[][] matrix,int a,int b,int c,int d){ int[][] D = new int[matrix.length][matrix[0].length]; for(int i=0;i<D.length;i++) for(int j=0;j<D[0].length;j++) D[i][j] = Integer.MAX_VALUE; D[a][b] = matrix[a][b]; int x=a,y=b; while(true){ // 计算 x y 节点到上下左右四个方向的路径,若小则更新 // 下 if(x < D.length -1) if(D[x+1][y] > 0) D[x+1][y] = Math.min(matrix[x+1][y] + D[x][y], D[x+1][y]); // 右 if( y<D[0].length -1) if(D[x][y+1] >0) D[x][y+1] = Math.min(matrix[x][y+1] + D[x][y], D[x][y+1]); //上 if(x>0) if(D[x-1][y] >0) D[x-1][y] = Math.min(matrix[x-1][y] + D[x][y], D[x-1][y]); // 左 if(y>0) if(D[x][y-1]>0) D[x][y-1] = Math.min(matrix[x][y-1] + D[x][y], D[x][y-1]); if(x==c && y==d) return D[x][y]; // 访问过的节点取其相反数 D[x][y] =-D[x][y]; // 选取下一个节点 // 在未被访问的节点中,选取路径值最小的 int min = Integer.MAX_VALUE; for(int i=0;i< D.length;i++){ for(int j=0;j<D[0].length;j++){ if(D[i][j]>0 && D[i][j] < min){ min = D[i][j]; x = i; y = j; } } } } } public static int Path_min(int[][] A){ int size = A.length; int B[][] = new int[size][size]; B[0][0] = A[0][0]; B[0][1] = A[0][0] + A[0][1]; B[1][0] = A[0][0] + A[1][0]; for(int i = 1;i<size; i++){ for(int j = 1;j<size ;j++){ B[i][j] = A[i][j] + get4min(B[i-1][j],B[i+1][j], B[i][j-1],B[i][j+1]); } } return B[size-1][size-1]; } public static int get4min(int a,int b,int c,int d){ int min1 = Math.min(a, b); int min2 = Math.min(c, d); return Math.min(min1, min2); } // 每行的数据添加到数组中 public static void populateArray(String str,int row){ int counter = 0; String[] data = str.split(","); for(int index = 0;index<=data.length -1;++index){ grid[row][counter++] = Integer.parseInt(data[index]); } } public static void assignArray(int no_of_row){ grid = new int[no_of_row][no_of_row]; } public static void main(String[] args) throws IOException{ long t0 = System.currentTimeMillis(); run(); long t1 = System.currentTimeMillis(); long t = t1 - t0; System.out.println("running time="+t/1000+"s"+t%1000+"ms"); // 425185 // running time=0s187ms } }
Java Code
相关文章推荐
- 初识体系结构
- IP控件
- 基于CSS3的苹果套件
- Studio中使用Svn详解
- NYOJ 168-房间安排
- OC_ARC学习笔记
- 微信管理手册(3)
- 给VS2008 打补丁
- ORA-28000: the account is locked-的解决办法
- Bmob文档阅读1-快速接入
- 杭电ACM1248(完全背包)
- grub 解析
- 网站开发进阶(十七)Html元素隐藏的几种方式
- 50道Java线程面试题
- 1087. All Roads Lead to Rome (30)
- 标记文件
- Linux Advance--目录下文件类型统计
- 网站开发进阶(十七)Html元素隐藏的几种方式
- 1087. All Roads Lead to Rome (30)
- POJ1088(记忆化搜索)