求任意大小矩陣兩點之間的最短路徑(回溯)
今天在某個公司的筆試題目上做到了一個題目:
任意給定兩個正半軸座標點,求最短路徑。
因為短時間很難寫出動態規劃,而且自己對動態規劃的理解也不夠深刻。所以能想到的就是回溯。
首先:給定起點和終點,求最短路徑,一共有八個方向
如果每次都在原有矩陣上跑,開銷太大了,於是採用擷取範圍的思想,將起
點和終點作為新矩陣的頂點進行擷取,建立新矩陣,更新座標,然後在此基
礎上找一個最短路徑出來
package com.test;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Stack;
public class findShortWay {
//定義從上開始,順時針跑八個方向
private int rowStep[] = {-1,-1,0,1,1,1,0,-1};
private int colStep[] = {0,1,1,1,0,-1,-1,-1};
//方向對映關係
private String stepMappint[] ={"U","UR","R","RD","D","LD","L","UL"};
Stack<Integer> minStack = null;
private int endX,endY;
public static void main(String[] args) {
new findShortWay().dispatcherMethod();
}
//字元轉數字 因為此公司是橫座標是字母
//本程式碼沒有做輸入轉數字的處理
public int char2Int(char c) throws IllegalArgumentException{
if(c >= 'a' && c <= 'z'){
return c-'a';
}else if(c >= 'A' && c<= 'Z' ){
return c-'A';
}else{
throw new IllegalArgumentException("輸入不是字母");
}
}
//初始化
private void init(int arr[][]){
for(int i=0;i<arr.length;i++){
for (int j = 0; j < arr[i].length; j++) {
arr[i][j] = 0;
}
}
}
/**
* 核心處理類(排程器)
*/
public void dispatcherMethod(){
int startX,startY;
//輸入起始座標和結束座標
Scanner in = new Scanner(System.in);
startX=in.nextInt();
startY=in.nextInt();
endX=in.nextInt();
endY=in.nextInt();
//處理輸入異常
if(startX==endX && startY==endY){
System.out.println("原地不動");
return;
}else if(startX<0 || endX<0 || startY<0 || endY<0){
System.out.println("輸入異常");
return;
}
//構建最小矩陣
int arr[][] = new int[Math.abs(startX-endX)+1][Math.abs(startY-endY)+1];
init(arr);
//更新座標
int num = getMin(startX,endX);
startX = subtrac(startX,num);
endX = subtrac(endX,num);
num = getMin(startY,endY);
startY = subtrac(startY,num);
endY = subtrac(endY,num);
//定義中轉棧
Stack<Integer> stack = new Stack<Integer>();
horseRun(stack,arr,startX,startY);
realShortWay();
}
private int getMin(int x,int y){
return x>y?y:x;
}
private int subtrac(int x,int y){
return x-y;
}
private void horseRun(Stack<Integer> stack,int arr[][],int startX,int startY){
arr[startX][startY]=1;
//遍歷八個需要走的路徑
for(int i=0;i<8;i++){
//試步操作
startX +=rowStep[i];
startY +=colStep[i];
//判斷是否可以走
if(canWalk(arr,startX,startY)){
//每次符合的壓棧
stack.push(i);
//判斷是否到終點
if(startX==endX && startY==endY){
Stack<Integer> newStack = new Stack<Integer>();
newStack.addAll(stack);
//判斷是否是第一次找到路徑,或者是否比最短路徑短
if(minStack==null || stack.size()<minStack.size()){
//如果跑到終點,和最小棧的長度進行比較,更替
minStack = newStack;
}
}else{
horseRun(stack,arr,startX,startY);
}
stack.pop();
}
startX -=rowStep[i];
startY -=colStep[i];
}
arr[startX][startY]=0;
}
//判斷本位置是否符合走步要求
private boolean canWalk(int arr[][],int x,int y){
if(x<0 || x>=arr.length || y<0 || y>=arr[x].length){
return false;
}
if(arr[x][y] != 0){
return false;
}
return true;
}
//語言描述真實最短路徑
public void realShortWay(){
if(minStack == null){
System.out.println("迷宮沒有找到解");
return;
}
Iterator<Integer> minStackIter = minStack.iterator();
while(minStackIter.hasNext()){
Integer i = minStackIter.next();
System.out.print(stepMappint[i]+" ");
}
System.out.println();
}
}
易錯點:
1. 建立新矩陣陣列的時候容易忘記終點和起點的座標做差會少計算一個單元的數值。
2. 因為是解演算法題,所以是沒有必要有提示語句的,此處是為了程式方便理解
3. 更新座標那裡,我還沒有想到更好的方法,如果有人想到了請給我發郵件[email protected]
程式真長。。還沒有加字元轉換功能呢~還是不符合題意。因為非常簡單,考察字串的拆分,大家可以自己嘗試實現
相關推薦
求任意大小矩陣兩點之間的最短路徑(回溯)
今天在某個公司的筆試題目上做到了一個題目: 任意給定兩個正半軸座標點,求最短路徑。 因為短時間很難寫出動態規劃,而且自己對動態規劃的理解也不夠深刻。所以能想到的就是回溯。 首先:給定起點和終點,求最短路徑,一共有八個方向 如果每次都在原有矩陣上跑,
兩點之間最短路徑:弗洛伊德算法
int code 指定 matrix ++ 計算 之間 logs 執行函數 弗洛伊德算法是計算無向有權圖中兩點間最短路徑的算法,復雜度為O(n^3)。其思路是將兩點間距離分為過(指定的)第三點或是不過,然後取它們的最小值,如此循環就可以得到兩點之間真正的最小值。 void
求圖中兩點最短路徑(dijkstra) go實現
import ( "testing" "strconv" "fmt" ) // V - S = T type Dijkstra struct { Visit bool // 表示是否訪問 Val int // 表示距離 Path string // 路徑的顯示 }
無向圖的Dijkstra演算法(求任意一對頂點間的最短路徑)迪傑斯特拉演算法
public class Main{ public static int dijkstra(int[][] w1,int start,int end) { boolean[] isLable = new boolean[w1[0].length];//是否標上所有的號 i
最短路徑(二)—Dijkstra演算法(通過邊實現鬆弛:鄰接矩陣)
上一節通過Floyd-Warshall演算法寫了多源節點最短路徑問題: 這一節來學習指定一個點(源點)到其餘各個頂點的最短路徑。也叫做“單源最短路徑”Dijkstra。 例如求下圖中1號頂點到2、3、4、5、6號頂點的最短路徑。 用二維陣列e儲存頂點之間邊的關係,初
演算法學習——動態規劃 例題:矩陣最短路徑(java)
給定一個矩陣m,從左上角開始每次只能向右或者向下走,最後到達右下角的位置, 路徑上所有的數字累加起來就是路徑的和,返回所有的路徑中的最小的路徑的和。 如果給定的m如大家看到的樣子,路徑1,3,1,0,6,1,0是所有路徑中路徑和最小的,所以返回12. 1 3 5 9 8 1 3 4 5 0 6 1
[模板]單源最短路徑(Dijkstra)
。。 str using while isdigit etc strong sin inline 如題,給出一個有向圖,請輸出從某一點出發到所有點的最短路徑長度。 主要還是再打一遍最短路,這種算法我用的不多。。。 1 #include<bits/std
單源最短路徑(Dijkstra)——貪心演算法
Dijkstra演算法是解單源最短路徑問題的貪心演算法。其基本思想是,設定頂點集合點集合S並不斷地做貪心選擇來擴充這個集合。一個頂點屬於集合S當且僅當從源到該頂點的最短路徑長度已知。初始時,S中僅含有源。設u是G的其一頂點。把從源到u且中間只經過S中頂點的路稱為從源到u的特殊
程式設計基礎31 tips 圖的最短路徑(三)
1072 Gas Station (30 分) A gas station has to be built at such a location that the minimum distance between the station and any of the residential ho
程式設計基礎30 tips 圖的最短路徑(二)
1018 Public Bike Management (30 分) There is a public bike service in Hangzhou City which provides great convenience to the tourists from all over th
程式設計基礎29 圖的最短路徑(一)
1003 Emergency (25 分) As an emergency rescue team leader of a city, you are given a special map of your country. The map shows several scattered cit
資料結構作業17—最短路徑(選擇題)
2-1資料結構中Dijkstra演算法用來解決哪個問題? (1分) A.字串匹配 B.最短路徑 C.拓撲排序 D.關鍵路徑 作者: DS課程組 單位: 浙江大學 2-2若要求在找到從S到其他頂點最短路的同時,還給出不同的最短路
SDUT 2622 最短路徑(Dijkstra)
點我看題目 題意 :中文不詳述。 思路 :因為這個題加了一個要求就是路徑數目得是x的倍數。所以在原來演算法的一維dis陣列增加到二維,用來存走的路徑數%x。也可以用spfa做。 #include <stdio.h> #include <string.h> #inclu
最短路徑(一)——多源最短路徑
引出問題:多源最短路徑的問題 暑假,小文準備去一些城市旅遊。為了節省經費以及方便計劃旅程,小文希望知道任意兩個城市之間的最短路徑。假如有四個城市八條公路。 我們這時怎麼做? 首先用一個數據結構來儲存圖的資訊,因為是四個城市就可以選擇4*4的矩陣:
圖結構練習——最短路徑(Dijkstra)
圖結構練習——最短路徑 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 給定一個帶權無向圖,求節點1到節點n的最短路徑。 Input 輸入包含多組資料,格式如下。 第一行包
AOJ GRL_1_C: All Pairs Shortest Path (Floyd-Warshall算法求任意兩點間的最短路徑)(Bellman-Ford算法判斷負圈)
self logs var inf sel main rain test rect 題目鏈接:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_1_C All Pairs Shortest
【最短路】求兩點間最短路徑的改進的Dijkstra算法及其matlab實現
inf 效率 func 圖論 表示圖 function nes 航空航天 ogr 代碼來源:《圖論算法及其matlab實現》(北京航空航天出版社) P18 書中提出了基於經典Dijkstra算法改進的兩種算法。 其中算法Ⅱ的效率較高。 代碼如下: 1 functio
經典演算法之Floyd演算法(求圖中任意一對頂點間的最短路徑)
/************************ author's email:[email protected] date:2018.1.30 *********************
經典演算法之Dijkstra演算法(求圖中任意一對頂點間的最短路徑)
/************************ author's email:[email protected] date:2018.1.30 ************************/ /* 迪傑斯特拉演算法思想: 設有兩個頂點集合S和T,集合S中
POJ 3255 Roadblocks (Dijkstra求最短路徑的變形)(Dijkstra求次短路徑)
ber emp accept backtrack cau scrip 直接 hang input Roadblocks Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 16425 Ac