【题目描述】
AcWing 1101. 献给阿尔吉侬的花束
【思路】
BFS 使用状态数组st
如果把状态数组st的代码去掉 会陷入死循环 所以在标记状态时要考虑清楚。最好是使用状态数组,比较容易理解。
import java.util.Scanner;
import java.util.LinkedList;
import java.util.Queue;
class Node{
int x, y, step;
public Node(int xx, int yy, int stepp){
x = xx;
y = yy;
step = stepp;
}
}
public class Main{
static int R = 210;
static int dir[][] = {{-1, 0}, {0, 1}, {1, 0}, {0, - 1}};
public static void main(String args[]){
Scanner reader = new Scanner(System.in);
int T = reader.nextInt();
while(T-- >0){
int r = reader.nextInt(), c = reader.nextInt();
char[][] g= new char[R][R];
boolean st[][] = new boolean[R][R];
for(int i = 0; i < r; i ++)
g[i] = reader.next().toCharArray();
int sx = 0, sy = 0;
for(int i = 0; i < r; i ++)
for(int j = 0; j < c; j ++)
if(g[i][j]=='S'){
sx = i;
sy = j;
}
Queue<Node> q = new LinkedList<Node>();
q.offer(new Node(sx, sy, 0));
st[sx][sy] = true;
boolean f = false;
int ans = 0;
while(!q.isEmpty()){
Node h = q.poll();
int x = h.x, y = h.y, step = h.step;
if(g[x][y] == 'E'){
ans = step;
f = true;
break;
}
g[x][y] = '#';
//从当前位置扩展四个方向节点入队列
for(int i = 0; i < 4; i ++){
int a = x +dir[i][0], b = y + dir[i][1];
if( a < 0 || a >=r || b < 0 || b >= c || g[a][b] == '#'||st[a][b]) continue;
q.offer(new Node(a, b, step + 1));
st[a][b] = true;
}
}
if(f)
System.out.println(ans);
else
System.out.println("oop!");
}
}
}
如果不使用状态数组st,个人比较推崇下面这种写法,在入队列时就将其标记 为访问过。否则很容易陷入死循环。
import java.util.Scanner;
import java.util.LinkedList;
import java.util.Queue;
class Node{
int x, y, step;
public Node(int xx, int yy, int stepp){
x = xx;
y = yy;
step = stepp;
}
}
public class Main{
static int R = 210;
static int dir[][] = {{-1, 0}, {0, 1}, {1, 0}, {0, - 1}};
static char[][] g= new char[R][R];
public static String bfs(int sx, int sy, int r, int c){
Queue<Node> q = new LinkedList<Node>();
q.offer(new Node(sx, sy, 0));
g[sx][sy] = '#';
while(!q.isEmpty()){
Node h = q.poll();
int x = h.x, y = h.y, step = h.step;
//从当前位置扩展四个方向节点入队列
for(int i = 0; i < 4; i ++){
int a = x +dir[i][0], b = y + dir[i][1];
if( a < 0 || a >=r || b < 0 || b >= c || g[a][b] == '#') continue;
if(g[a][b] == 'E') return ""+(step + 1);
g[a][b] = '#'; //标记已经走过
q.offer(new Node(a, b, step + 1));
}
}
return "oop!";
}
public static void main(String args[]){
Scanner reader = new Scanner(System.in);
int T = reader.nextInt();
while(T-- >0){
int r = reader.nextInt(), c = reader.nextInt();
for(int i = 0; i < r; i ++)
g[i] = reader.next().toCharArray();
int sx = 0, sy = 0;
for(int i = 0; i < r; i ++)
for(int j = 0; j < c; j ++)
if(g[i][j]=='S'){
sx = i;
sy = j;
}
System.out.println(bfs(sx, sy, r, c));
}
}
}