奇妙的算法【3】- 貪心算法【待完成】

 

 

問題1:尋找最優路徑【Breadth First Search】

這個和貪婪算法不同,這個屬於遍歷全部節點

假設以一個n*m的矩陣做爲棋盤,每一個棋位對應一個二維座標 (x, y)。
你有一顆棋子位於左上起點(0, 0),如今須要將其移動到右下底角 (n-1, m-1),
棋子能夠向相鄰的上下左右位置移動,每一個座標最多隻能通過一次。
棋盤中散佈着若干障礙,障礙物不能跨越,只能繞行,問是否存在到達右下底角的路線?若存在路線,輸出所需的最少移動次數;
若不存在,輸出0。
Input 第一行三個正整數n,m和k,表明棋盤大小與障礙物個數  1< n、m < 100,  k < n*m 第二行至第k+1行,
每行爲兩個整數x和y,表明k個障礙物的座標。
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;

class Loc{
    int x,y,step;
    public Loc(int x,int y,int step){
        this.x=x;
        this.y=y;
        this.step=step;
    }
}

public class Main {//應該是要使用到廣度搜索算法
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt(),m=sc.nextInt(),k=sc.nextInt();
        int[][] map=new int[n][m];
        for(int i=0;i<k;i++){
            map[sc.nextInt()][sc.nextInt()]=1;
        }

        int ans=0;
        Queue<Loc> queue=new LinkedList<Loc>();
        queue.add(new Loc(0,0,0));
        while (queue.size()>0){
            Loc pre=queue.poll();
            if(pre.x==n-1&&pre.y==m-1){//到達終點
//                System.out.println("到達終點");
                ans=pre.step;
                break;
            }
            map[pre.x][pre.y]=1;
            //向右
            if(pre.y+1<m&&map[pre.x][pre.y+1]==0){
                queue.add(new Loc(pre.x,pre.y+1,pre.step+1));
            }

            //向下
            if(pre.x+1<n&&map[pre.x+1][pre.y]==0){
                queue.add(new Loc(pre.x+1,pre.y,pre.step+1));
            }

            //向左
            if(pre.y-1>=0&&map[pre.x][pre.y-1]==0){
                queue.add(new Loc(pre.x,pre.y-1,pre.step+1));
            }

            //向上
            if(pre.x-1>=0&&map[pre.x-1][pre.y]==0){
                queue.add(new Loc(pre.x-1,pre.y,pre.step+1));
            }
        }
        System.out.println(ans);
    }
}

 

問題2:尋找最優路徑-變形【Breadth First Search】

薯隊長最近在玩一個迷宮探索類遊戲,迷宮是一個N*N的矩陣形狀,
其中會有一些障礙物禁止經過。這個迷宮還有一個特殊的設計,
它的左右邊界以及上下邊界是連通的,好比在(2,n)的位置繼續往右走一格能夠到(2,1),
在(1,2)的位置繼續往上走一格能夠到(n,2)。

請問薯隊長從起點位置S,最少走多少格才能到達迷宮的出口位置E。
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

class Loc{
    int x,y,step;
    public Loc(int x,int y,int step){
        this.x=x;
        this.y=y;
        this.step=step;
    }
}

public class Main2 {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int N=sc.nextInt();
        int[][] sinMap=new int[N][N];
        int[][] map=new int[N*3][N*3];

        String temp;
        int value=0;
        int[] index0=new int[2];
        for(int i=0;i<N;i++){
            temp=sc.next();
            for(int j=0;j<N;j++){
//                System.out.println("j:"+j+",temp:"+temp+",char:"+temp.charAt(j));
                switch (temp.charAt(j)){
                    case '.':
                        value=0;
                        break;
                    case '#':
                        value=-1;
                        break;
                    case 'S':
                        value=1;
                        break;
                    case 'E':
                        value=2;
                        break;
                }
                if(value==-1){
                    sinMap[i][j]=-1;
                }else if(value==1){
                    index0[0]=i+N;
                    index0[1]=j+N;
                }else if(value==2){
                    sinMap[i][j]=1;
                }
            }
        }

        for(int i=0;i<3;i++){
            for(int j=0;j<3;j++){
                //sinMap塊進行復制粘貼
                for(int ii=0;ii<N;ii++) {
                    for (int jj = 0; jj < N; jj++) {
                        map[i*N+ii][j*N+jj]=sinMap[ii][jj];
                    }
                }

            }
        }

        N*=3;
        int ans=0;
        Queue<Loc> queue=new LinkedList<Loc>();
        queue.add(new Loc(index0[0],index0[1],0));
        while (queue.size()>0){
            Loc pre=queue.poll();
            map[pre.x][pre.y]=-1;

            //向右
            if(pre.y+1<N&&map[pre.x][pre.y+1]!=-1){
                if(map[pre.x][pre.y+1]==1){
                    ans=pre.step+1;
                    break;
                }
                queue.add(new Loc(pre.x,pre.y+1,pre.step+1));
            }

            //向下
            if(pre.x+1<N&&map[pre.x+1][pre.y]!=-1){
                if(map[pre.x+1][pre.y]==1){
                    ans=pre.step+1;
                    break;
                }
                queue.add(new Loc(pre.x+1,pre.y,pre.step+1));
            }

            //向左
            if(pre.y-1>=0&&map[pre.x][pre.y-1]!=-1){
                if(map[pre.x][pre.y-1]==1){
                    ans=pre.step+1;
                    break;
                }
                queue.add(new Loc(pre.x,pre.y-1,pre.step+1));
            }

            //向上
            if(pre.x-1>=0&&map[pre.x-1][pre.y]!=-1){
                if(map[pre.x-1][pre.y]==1){
                    ans=pre.step+1;
                    break;
                }
                queue.add(new Loc(pre.x-1,pre.y,pre.step+1));
            }
        }
        System.out.println(ans);
    }
}

/*
4
#S..
.#..
.E..
##..
 */

 

問題3:帶權重的最優路徑規劃【標準的貪婪算法】

每次只選擇最小的數據進行運行,有一個優先隊列

相關文章
相關標籤/搜索