穿越雷区

1、问题描述

某坦克需要从A区到B区去(A,B区本身是安全区,没有正能量或负能量特征),怎样走才能路径最短?

已知的地图是一个方阵,上面用字母标出了A,B区,其它区都标了正号或负号分别表示正负能量辐射区。
例如:
A + - + -
- + - - +
- + + + -
+ - + - +
B + - + -

坦克车只能水平或垂直方向上移动到相邻的区。

数据格式要求:

输入第一行是一个整数n,表示方阵的大小, 4<=n<100
接下来是n行,每行有n个数据,可能是A,B,+,-中的某一个,中间用空格分开。
A,B都只出现一次。

要求输出一个整数,表示坦克从A区到B区的最少移动步数。
如果没有方案,则输出-1

例如:
用户输入:
5
A + - + -
- + - - +
- + + + -
+ - + - +
B + - + -

则程序应该输出:
10

2、思路

利用DFS搜索,要加坦克移动的四个方向,题目中的交替穿越正负能量雷区,只要把他转化为这里走的雷区与下一次要走的类型不相等就可以了,具体的情况请看代码,代码中有详细的注解

3、代码

/**
 * 穿越雷区
 * @description
 * @author zhangbiao
 * @time 2018-5-22 下午3:36:56
 */
public class Main09 {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        n=sc.nextInt();
        //初始化数据
        map=new char[n][n];
        vis=new int[n][n];
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                char temp=sc.next().charAt(0);
                if(temp=='+'||temp=='-'){
                    map[i][j]=temp;

                }else if(temp=='A'){
                    xA=i;
                    yA=j;
                    map[i][j]='A';

                }else if(temp=='B'){
                    xB=i;
                    yB=j;
                    map[i][j]='B';
                }
            }
        }
        vis[xA][yA]=1;  //A雷区已经被访问
        dfs(xA, yA, '0', 0);
        System.out.println(stepMin);
    }
    static int xA,xB,yA,yB; //记录A,B的坐标
    static char[][] map;    //记录雷区
    static int[][] vis;     //记录是否被访问
    static int n;           //方针阵大小
    static int stepMin=Integer.MAX_VALUE;   //最小路径值
    static int[][] next={{0,1},{0,-1},{1,0},{-1,0}};    //上下左右四个方向

    /**
     * dfs搜索
     * @param x 雷区的横坐标
     * @param y 雷区的纵坐标
     * @param ch 雷区的类型
     * @param step 走过的路径值
     */
    public static void dfs(int x,int y,char ch,int step){
        //到达B雷区
        if(x==xB&&y==yB){
            //记录最小值
            if(stepMin>step){
                stepMin=step;
            }
            return ;
        }
        int tx,ty;
        for(int i=0;i<4;i++){
            tx=x+next[i][0];
            ty=y+next[i][1];
            //过滤不符合条件的走法
            if(tx<0||ty<0||ty>=n||tx>=n){
                continue ;
            }
            //注意:这里的map[tx][ty]!=ch表明这次走的雷区与下次要走的雷区不相等
            //这里既是题目要求的正负雷区交替走
            if(vis[tx][ty]==0&&map[tx][ty]!=ch){
                vis[tx][ty]=1;
                dfs(tx, ty, map[tx][ty], step+1);
                vis[tx][ty]=0;
            }
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值