P1825 [USACO11OPEN] Corn Maze S
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Main {
public static int N;//行
public static int M;//列
public static Queue<Integer> q = new LinkedList<>();
public static int[] x = new int[]{1, -1, 0, 0};
public static int[] y = new int[]{0, 0, 1, -1};
public static char[][] map = new char[305][305];
public static int[][] visit = new int[305][305];
public static int[][] step = new int[305][305];
public static int flag = 0;
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
N = scan.nextInt();
M = scan.nextInt();
for (int i = 0; i < N; i++) {
map[i] = scan.next().toCharArray();
}
bfs();
}
public static void bfs() {
int f = 0;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (map[i][j] == '@') {
q.add(i);
q.add(j);
step[i][j] = 0;
visit[i][j] = 1;
f = 1;
break;
}
}
if (f == 1) {
break;
}
}
while (!q.isEmpty()) {
int row = q.poll();
int col = q.poll();
boolean flag = true;
int x1=row;
int y2=col;
if(map[row][col]=='='){
System.out.println(step[row][col]);
return;
}
if (map[row][col] >= 'A' && map[row][col] <= 'Z') {
for (int i = 0; i < N && flag; i++) {
for (int j = 0; j < M && flag; j++) {
if (map[i][j] == map[row][col] && (i != row || j != col)) {
row = i;
col = j;
flag = false;
}
}
}
}
for (int i = 0; i < 4; i++) {
int r = row + x[i];
int c = col + y[i];
if(r>=0&&r<N&&c>=0&&c<M&&visit[r][c]==0&&map[r][c]!='#'){
step[r][c]=step[x1][y2]+1;
visit[r][c]=1;
q.add(r);
q.add(c);
}
}
}
}
思路:
这道题与往常的模板有一个小小的不同,往常是将预备入队的元素进行检查,如果发现有我们需要的答案则直接结束,输出step+1,而如果有可以继续走的元素则入队,step+1.
而这题我们是将将要出队的元素进行检查。
因为如果出队的是装置,我们就会跳到另外一个装置,然后对这个装置的四周进行判断是否要入队。而判断是否入队则是不是'#'就可以入队了。
如果出队的恰好是'=',我们就可以直接输出这个元素的step了。
注意点:
int x1=row;
int y2=col;
如果出队的是装置,那么我们要保留这个原装置的步数,因为如果我们把原装置的步数赋值给新装置,那么新装置自己的步数就被覆盖掉了,当进行下一次这个新装置出队时,又跳跃到旧,这个步数就是错的。这个就是测试点8的注意点。