Project Euler 83:Path sum: four ways 路径和:4个方向
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.
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 |
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,由标注红色的路径给出。
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 |
在这个31K的文本文件matrix.txt (右击并选择“目标另存为……”)中包含了一个80乘80的矩阵,求出从左上角到右下角任意地向上、向下、向左或向右移动的最小路径和。
解题
表示很复杂,这个应该用到图,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" #
# 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
Project Euler 83:Path sum: four ways 路径和:4个方向的更多相关文章
- Project Euler 82:Path sum: three ways 路径和:3个方向
Path sum: three ways NOTE: This problem is a more challenging version of Problem 81. The minimal pat ...
- Project Euler 81:Path sum: two ways 路径和:两个方向
Path sum: two ways In the 5 by 5 matrix below, the minimal path sum from the top left to the bottom ...
- Leetcode 931. Minimum falling path sum 最小下降路径和(动态规划)
Leetcode 931. Minimum falling path sum 最小下降路径和(动态规划) 题目描述 已知一个正方形二维数组A,我们想找到一条最小下降路径的和 所谓下降路径是指,从一行到 ...
- 【LeetCode-面试算法经典-Java实现】【064-Minimum Path Sum(最小路径和)】
[064-Minimum Path Sum(最小路径和)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Given a m x n grid filled with ...
- [LeetCode] Path Sum II 二叉树路径之和之二
Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given su ...
- [LeetCode] Path Sum 二叉树的路径和
Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all ...
- [LeetCode] Binary Tree Maximum Path Sum(最大路径和)
Given a binary tree, find the maximum path sum. The path may start and end at any node in the tree. ...
- [LeetCode] 113. Path Sum II 二叉树路径之和之二
Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given su ...
- [LeetCode] 112. Path Sum 二叉树的路径和
Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all ...
随机推荐
- 大仙说道之Android studio实现Service AIDL
今天要开发过程中要用到AIDL的调用,之前用的eclipse有大量教程,用起来很方便,现在刚换了Android studio,不可否认studio真的很强大,只是很多功能还需要摸索. AIDL(And ...
- 一款仿PBA官网首页jQuery焦点图的切换特效
一款仿PBA官网首页jQuery焦点图的切换特效,非常的简单大方, 在对浏览器兼容性的方面做了不少的功夫.IE6也勉强能过去. 还是一款全屏的焦点图切换特效.大气而清新.很适合简介大方的网站. 下图还 ...
- Atan2
在三角函数中,两个参数的函数atan2是正切函数的 一个变种.对于任意不同时等于0的实参数x和y,atan2(y,x)所表达的意思是坐标原点为起点,指向(x,y)的射线在坐标平面上与x轴正方向之间 的 ...
- js实现模拟自动点击按钮,并且在10秒倒计时之后疯狂点击
需求来自于csdn问答,可以利用这个原理做秒杀抢单外挂. 代码示例如下: <html> <head> <meta charset="utf-8"/&g ...
- openerp学习笔记 webkit 打印
1.webkit 打印需要安装的支持模块 请首先安装 Webkit 报表引擎(report_webkit),再安装 Webkit 报表的支持库(report_webkit_lib),该模块讲自动安装和 ...
- find命令小结
find命令小结 find命令用于在系统中查找文件,配合 -exec 选项或 xargs命令还能对查找到得文件执行一些列的自动化操作. 基本格式:find [-H] [-L] [-P] [path.. ...
- pipe/popen/fifo
pipe(管道) 专用于父子进程通信, 函数原型 int pipe(int fd[2]) fd[0]表示输入, fd[1]表示输出 如果父子进程要双向通信, 可以通过类似信号的功能进行控制, 也可以简 ...
- linux 目录
创建和删除 int mkdir(const char *pathname, mode_t mode); int rmdir(const char *pathname); 另外remove也可以删除文件 ...
- linux 线程笔记
线程与进程关键字对比 创建新流 fork/pthread_create 退出控制流 exit/pthread_exit 获取退出状态 waitpid/pthread_join 在退出时的清理工作 at ...
- MYSQL 配置slave故障
之前为主从配置,后来分割成2个单实例.现在环境需要,重新配置为主从,之前参数都已配置好,直接启动,如下: mysql> change master to master_host='192.168 ...