蓝桥杯 穿越雷区

题目



题目描述:
X星的坦克战车很奇怪,它必须交替地穿越正能量辐射区和负能量辐射区才能保持正常运转,否则将报废。
某坦克需要从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



思路


DFS,为防止超时,需要优化剪枝



代码


import java.util.Scanner;

public class Main {
	static int min;
	static int totalLen;
    static boolean book[][] = new boolean[101][101];
    static int maze[][]= new int[101][101];
    static int n,xB,yB;
    static int dir[][]=new int[][]{{-1,0},{0,1},{1,0},{0,-1}};
    public static void main(String[] args) {
    	Scanner scan =new Scanner(System.in);
    	n=scan.nextInt();
    	scan.nextLine();
    	String str;
    	int xA=0,yA=0;
    	for(int i=0;i<n;i++) {
    		str = scan.nextLine();
    		String[] s= str.split(" ");
    		for(int j=0;j<n;j++) {
    			switch(s[j].charAt(0)) {            //储存地图
    			case '+' : maze[i][j] = 0;break;
    			case '-' : maze[i][j] = 1;break;
    			case 'A' : maze[i][j] = 2;xA=i;yA=j;break;
    			case 'B' : maze[i][j] = 3;xB=i;yB=j;break;
    			default :break;
     			}
    		}
    	}
    	for(int i=0;i<n;i++) {for(int j=0;j<n;j++) {
    		book[i][j] = false;
    		}
    	}
		min = 1<<30;
		totalLen = 0;
		dfs(xA,yA);
		if(min< 1<<30) {
			System.out.println(min);
		}
		else {
			System.out.println("-1");
		}
		
    } 
    private static void dfs(int x,int y) {
    	int tx,ty;
    	if(x==xB&&y==yB) {
    		if(totalLen<min) {
    			min=totalLen;
    		}
    		return;
    	}
    	if(x<0||y<0||x>n-1||y>n-1) {
    		return;
    	}
    	
    	if(totalLen == min) {return;}        //剪枝
    	for(int i=0;i<4;i++) {
    		tx=x+dir[i][0];
    		ty=y+dir[i][1];
    		if(tx<0||tx>n-1||ty<0||ty>n-1){
    				continue;
    				}
    		if(maze[tx][ty]!=maze[x][y] && !book[tx][ty]) {
        	book[tx][ty]=true;
        	totalLen++;
        	dfs(tx,ty);
        	totalLen--;
        	book[tx][ty]=false;}
    	}
    
    }
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值