算法-水管工游戏

参考:《啊哈!算法》

1、题目

水管工游戏是指如下图中的矩阵中,一共有两种管道,一个是直的,一个是弯的,所有管道都可以自由旋转,最终就是要连通入水口可出水口。其中的树为障碍物。

这里写图片描述

这里写图片描述

2、算法思路

本题使用的是深度优先搜索算法,先标识入水口方向,在每次探索新管道的时候上根据入水口方向进行扩展,然后根据管道的类型来判断下一个节点的入水口方向。

3、代码

package 搜索.广度优先搜索BFS.水管工游戏;

import java.util.Scanner;

public class Main {
    private static int[][] map;         //存储管道图
    private static int n, m, top;       //管道的矩阵x,y, top栈顶元素
    private static boolean[][] status;  //是否已使用
    private static String[] stack;      //栈

    /**
     *
     * @param x 坐标x
     * @param y 坐标y
     * @param direction 进水口方向:1上、2右、3下、4左
     */
    private static void  dfs(int x, int y, int direction){
        if(x == n-1 && y == m){     //如果到出口的下一个则表示完成一条路径
            System.out.println("搜索到连通路线");
            for (int i = 0; i < top;i++){
                System.out.print(stack[i]+"->");
            }
            System.out.println();
            return ;
        }

        if(y < 0 || x < 0|| x > n-1 || y > m-1 || status[x][y])
            return;

        status[x][y] = true;
        stack[top] = "("+(x+1)+","+(y+1)+","+direction+")";     //入栈
        top++;


        if (5 <= map[x][y] && map[x][y] <= 6){      //如果是直管道
            switch (direction){
                case 1:
                    dfs(x+1, y, direction);
                    break;
                case 2:
                    dfs(x, y-1, direction);
                    break;
                case 3:
                    dfs(x-1, y, direction);
                    break;
                case 4:
                    dfs(x, y+1, direction);
                    break;
            }

        }else{
            switch (direction){     //弯管道
                case 1:
                    dfs(x, y-1, 2);
                    dfs(x, y+1, 4);
                    break;
                case 2:
                    dfs(x-1, y, 3);
                    dfs(x+1, y, 1);
                    break;
                case 3:
                    dfs(x, y-1, 2);
                    dfs(x, y+1, 4);
                    break;
                case 4:
                    dfs(x-1, y, 3);
                    dfs(x+1, y, 1);
                    break;
            }
        }

        status[x][y] = false;
        top--;
    }

    public static void main(String[] ages){
        Scanner scanner = new Scanner(System.in);
        n = scanner.nextInt();
        m = scanner.nextInt();

        map = new int[n][m];
        status = new boolean[n][m];
        stack = new String[n*m];
        for (int i = 0; i < n; i++){
            for (int j = 0; j < m; j++){
                map[i][j] = scanner.nextInt();
            }
        }

        dfs(0,0, 4);
    }
}

/**
 测试数据:
 5 4
 5 3 5 3
 1 5 3 0
 2 3 5 1
 6 1 1 5
 1 5 5 4
 结果:
 搜索到连通路线
 (1,1,4)->(1,2,4)->(2,2,1)->(3,2,1)->(3,3,4)->(3,4,4)->(4,4,1)->(5,4,1)->
 */
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值