class Solution {
class Nagoto {
int x;
int y;
int rest;
Nagoto(int x, int y, int rest) {
this.x = x;
this.y = y;
this.rest = rest;
}
}
public int shortestPath(int[][] grid, int k) {
int m = grid.length;
int n = grid[0].length;
if (m == 1 && n == 1)
return 0;
int[][] directions = new int[][]{{1,0},{0,1},{-1,0},{0,-1}};
k = Math.min(k, m + n - 3);
boolean[][][] visited = new boolean[m][n][k+1];
Queue<Nagoto> queue = new LinkedList<>();
queue.offer(new Nagoto(0, 0, k));
int step = 1;
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
Nagoto cur = queue.poll();
for (int[] dir : directions) {
int nextX = cur.x + dir[0];
int nextY = cur.y + dir[1];
if (nextX < 0 || nextX > m - 1 || nextY < 0 || nextY > n - 1)
continue;
if (nextX == m - 1 && nextY == n - 1)
return step;
if (grid[nextX][nextY] == 0 && !visited[nextX][nextY][cur.rest]) {
queue.offer(new Nagoto(nextX, nextY, cur.rest));
visited[nextX][nextY][cur.rest] = true;
} else if (grid[nextX][nextY] == 1 && cur.rest > 0 &&
!visited[nextX][nextY][cur.rest - 1]){
queue.offer(new Nagoto(nextX, nextY, cur.rest - 1));
visited[nextX][nextY][cur.rest - 1] = true;
}
}
}
step++;
}
return -1;
}
}