目录
题目
解析(BFS)
通过题目可以很明显看出是一个求在二维坐标上最短路问题,可以用BFS和DFS进行,这个题多一个条件就是要,要先走k个A,然后走k个B。
因此,使用一般的BFS不能解决问题,一般的BFS
Queue<int[]> q = new LinkedList<>();
q.add(new int[]{1,1});
while(!q.isEmpty()){
int[] t = q.poll();
int x = t[0], y = t[1];
for(int i=0;i<4;i++){
int x1 = x+dx[i];
int y1 = y+dy[i];
if(x1>0&&x1<=n&&y1>0&&y1<=m&&...){
// 更新距离
// if(!st[x1][y1]) q.add(new int[]{x1,y1}); // 如果是第一次走(x1,y1),加入队列
}
}
}
因为有 k 这个条件,因此我们在BFS中,要有三个状态,x,y,以及 cnt。cnt表示一共连续走了多少个 A 或 B。
BFS 拓展时,判断一个状态的正确性,
1.判断坐标有没有出界。
2.我们只能判断当前这一个点是不是合法。可以分两种情况讨论:
如果当前的 cnt 值为 k 且扩展后状态坐标上的字母等于扩展前的,那么当前状态不合法。
如果当前的 cnt 值 < k 且扩展后状态坐标上的字母不等于扩展前的,那么当前状态不合法。
一般的BFS,每个点最多走一次,但是由于此题的特殊性,最优解的点不一定是在BFS中第一次到达的点(可以这样理解,该题的解要经过()该点,但不是第一次到达该点的路径)。每个点可能会被重复走,因此使用二维dist[][]来存储最短路径是不合适的。
因此我们需要多一维,定义 表示第 𝑖 行 𝑗 列到达时走过恰好 𝑘 个 A 或 B 时最少需要走多少步。这样,我们在输出的时候,就可以直接将里面的元素取最小值输出就可以了。
代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
//P9425 [蓝桥杯 2023 国 B] AB 路线
public class P9425 {
static int N = 1010;
static int n,m,k;
static int[][] a = new int[N][N];
static int[][][] dist = new int[N][N][11];
static boolean[][][] st = new boolean[N][N][11];
static int[] dx = {0,1,-1,0};
static int[] dy = {1,0,0,-1};
public static void main(String[] args) throws IOException{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String[] s = in.readLine().split(" ");
n = Integer.parseInt(s[0]);
m = Integer.parseInt(s[1]);
k = Integer.parseInt(s[2]);
for (int i = 1; i <= n; i++) {
String str = in.readLine();
for (int j = 1; j <= m; j++) {
if(str.charAt(j-1)=='A') a[i][j] = 0;
else a[i][j] = 1;
}
}
Queue<int[]> q = new LinkedList<>();
q.add(new int[]{1,1,1});
st[1][1][1] = true;
while (!q.isEmpty()){
int[] t = q.poll();
int x = t[0], y = t[1], cnt = t[2];
for (int i = 0; i < 4; i++) {
int x1 = x+dx[i];
int y1 = y+dy[i];
int cnt1 = cnt+1;
if(x1<1||x1>n||y1<1||y1>m) continue;
if(a[x1][y1]==a[x][y]&&cnt>=k) continue;
if(a[x1][y1]!=a[x][y]&&cnt<k) continue;
if(cnt1>k)
cnt1 = 1;
if (st[x1][y1][cnt1]) continue;
st[x1][y1][cnt1] = true;
dist[x1][y1][cnt1] = dist[x][y][cnt]+1;
q.add(new int[]{x1,y1,cnt1});
}
}
int res = 0x3f3f3f3f;
for (int i = 1; i <= k; i++) {
if(st[n][m][i]) res = Math.min(res,dist[n][m][i]);
}
if(res != 0x3f3f3f3f) System.out.println(res);
else System.out.println(-1);
}
}