蓝桥杯 15决赛 B4 穿越雷区(bfs)

蓝桥杯 15决赛 B4 穿越雷区(bfs)

标题:穿越雷区
X星的坦克战车很奇怪,它必须交替地穿越正能量辐射区和负能量辐射区才能保持正常运转,否则将报废。
某坦克需要从A区到B区去(A,B区本身是安全区,没有正能量或负能量特征),怎样走才能路径最短?
已知的地图是一个方阵,上面用字母标出了A,B区,其它区都标了正号或负号分别表示正负能量辐射区。
例如:
坦克车只能水平或垂直方向上移动到相邻的区。

数据格式要求:
输入第一行是一个整数n,表示方阵的大小, 4<=n<100
接下来是n行,每行有n个数据,可能是A,B,+,-中的某一个,中间用空格分开。
A,B都只出现一次。
要求输出一个整数,表示坦克从A区到B区的最少移动步数。
如果没有方案,则输出-1
例如:
用户输入:
5
则程序应该输出:
10

在这里插入图片描述

资源约定:
峰值内存消耗(含虚拟机) < 512M
CPU消耗 < 2000ms

==============================

思路:
最短路径=>bfs

心得:
/**调试:输出光标从输入右边开始写出,不是在输入的下一行开始->少读了一行
下面是我最初的init()方法源码:

private static void init() {
	Scanner sc = new Scanner(System.in);
	
	n =sc.nextInt(); =>这里使用的nextInt()=>使得光标 还停在这一行,nextLine就不会这样(直接读到下一行)
	
	String s ="";
	for(int i =0 ;i <n ;i ++) s +=sc.nextLine().replace(" ", "");
	sc.close();
	c =s.toCharArray();
	isDone =new boolean[n *n];
	for(int i =0 ;i <c.length ;i ++) if(c[i] =='A') a =i; else if(c[i] =='B') b =i;
	
	总结一波:注意输入的读取光标位置,特别是同时使用nextInt和nextLine的时候
}*/
package cn.蓝桥.决赛15.B;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

/*
 @author weng
 @build  2020年7月21日 下午7:15:30
 TODO 
*/
public class bfs_穿越雷区_4 {
	static int n ,a ,b ;
	static char[] c;
	static boolean[] isDone;
	static Queue<Integer> q =new LinkedList<Integer>();
	static Queue<Integer> tmp =new LinkedList<Integer>();
	static int ans;
	public static void main(String[] args) {
		init();
		
		//读入 数据头
		q.add(a);
		isDone[a] =true;
		
		int[] oper = {-1 ,n ,1};
		int cur =0 ,next =0;
		while(true) {	//循环倒腾两个队列->bfs,每倒腾一轮 步数(ans)+1
			cur =q.poll();
			
			//遍历 操作数组
			for(int o :oper) {
				next =cur +o;
				
				//过滤
				if(next >=c.length) continue;	//数组边界判断
				else if(cur %n ==0 &&o ==-1) continue;	//数据边界判断
				else if((cur +1) %n ==0 &&o ==1) continue;
				else if(isDone[next]) continue;	//后面两条涉及数组边界问题,放在边界判断后面
				else if(c[cur] ==c[next]) continue;
				
				if(next ==b) {System.out.println(ans +1); return ;}
				tmp.add(next);
				isDone[next] =true;
			}
			
			if(q.size() ==0) {				
				if(tmp.size() ==0) {System.out.println(-1); return ;}
				while(tmp.size() !=0) q.add(tmp.poll());
				ans ++;
			}
		}
	}
	private static void init() {
		Scanner sc = new Scanner(System.in);
		n =Integer.parseInt(sc.nextLine());
		String s ="";
		for(int i =0 ;i <n ;i ++) s +=sc.nextLine().replace(" ", "");
		sc.close();
		c =s.toCharArray();
		isDone =new boolean[n *n];
		//n值不过100,其乘积不过10000,数组可接纳且读取不慢
		for(int i =0 ;i <c.length ;i ++) if(c[i] =='A') a =i; else if(c[i] =='B') b =i;
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_43638238/article/details/107499223