深度/广度优先搜索

还是借助上一篇文章中亲子游戏的例子说明一下深度优先搜索示例:


import java.util.*;

public class CandyGameDfs {
    //    <p>  宝宝和妈妈参加亲子游戏,在一个二维矩阵(N*N)的格子地图上,宝宝和妈妈抽签决定各自的位置,地图上每个格子有不同的糖果数量,部分格子有障碍物。 </p> <p>
//    游戏规则是妈妈必须在最短的时间(每个单位时间只能走一步)到达宝宝的位置,路上的所有糖果都可以拿走,不能走障碍物的格子,只能上下左右走。 </p> <div>
//    请问妈妈在最短到达宝宝位置的时间内最多拿到多少糖果(优先考虑最短时间到达的情况下尽可能多拿糖果)。 </div>
//    -3:妈妈
//    -2:宝宝
//    -1:障碍
//    ≥0:糖果数(0表示没有糖果,但是可以走)
//    4
//    3  2  1 -3
//    1 -1  1  1
//    1  1 -1  2
//   -2  1  2  3

    static int mi = 0,mj = 0,si = 0,sj = 0;
    static Queue<Pos> queue = null; //记录已访问节点
    static boolean[][] visited = null; //标记是否已访问
    static List<Pos> posList = null; //记录所有的路线
    static int[][] arr;
    static Pos end;
    static boolean fined;
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        final int n = scanner.nextInt();
        arr = new int[n][n];

        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; j++){
                arr[i][j] = scanner.nextInt();
                if(arr[i][j] == -3){
                    mi = i;
                    mj = j;
                }else if(arr[i][j] == -2){
                    si = i;
                    sj = j;
                }
            }
        }
        queue = new LinkedList<>(); //记录已访问节点
        visited = new boolean[n][n];
        posList = new LinkedList<>(); //记录所有的路线
        Pos start = new Pos(mi,mj,0); //开始位置
        end = new Pos(si,sj,0);
        dfsMs(start); //深度优先搜索

        System.out.println(posList.size());
        for(Pos pos : posList){
            int size = 0;
            int sum = 0;
            while (pos != null){
                System.out.println(pos.x + " " + pos.y + " "+ pos.count);
                pos = pos.pre;
                if(pos != null && pos.count > 0){
                    sum+=pos.count;
                    size++;
                }
            }
            System.out.println(size + 1 + " "+ sum);
            System.out.println("===");
        }

    }

    //这个还是深度搜索,deap first search,访问的方向对结果是有影响的。
    public static void dfsMs(Pos start){
        if(start.equals(end)){ //找到了
            posList.add(start);
            fined = true;
            return;
        }

        visited[start.x][start.y] = true; //已访问

        //向上
        if(start.x > 0 && !visited[start.x - 1][start.y] && arr[start.x - 1][start.y] != -1 && !fined){
            Pos tmp = new Pos(start.x-1,start.y,arr[start.x-1][start.y]);
            tmp.pre = start;
            dfsMs(tmp);
        }

        //向下
        if(start.x < arr.length-1 && !visited[start.x + 1][start.y] && arr[start.x + 1][start.y] != -1 && !fined){
            Pos tmp = new Pos(start.x+1,start.y,arr[start.x+1][start.y]);
            tmp.pre = start;
            dfsMs(tmp);
        }

        //向左
        if(start.y > 0 && !visited[start.x][start.y - 1] && arr[start.x][start.y-1] != -1 && !fined){
            Pos tmp = new Pos(start.x,start.y - 1,arr[start.x][start.y-1]);
            tmp.pre = start;
            dfsMs(tmp);
        }

        //向右
        if(start.y < arr.length - 1 && !visited[start.x][start.y+1] && arr[start.x][start.y+1] != -1 && !fined){
            Pos tmp = new Pos(start.x,start.y+1,arr[start.x][start.y+1]);
            tmp.pre = start;
            dfsMs(tmp);
        }
        //回溯
        if(start.pre != null && !fined){
            visited[start.pre.x][start.pre.y] = false;
            dfsMs(start.pre);
        }
    }

    static class Pos{
        int x;
        int y;
        int count;
        Pos pre;
        public Pos(int x,int y,int count){
            this.x = x;
            this.y = y;
            this.count = count;
        }


        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Pos pos = (Pos) o;
            return x == pos.x && y == pos.y;
        }

        @Override
        public int hashCode() {
            return Objects.hash(x, y);
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lx18854869896

和谐社会靠你了,老铁...

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值