带限制的最短路径可以用BFS,击败大蛇丸的手下相当于直接破坏迷宫的障碍行走。在不能破坏障碍的时候,我们使用vis数组来标记一个位置是否访问过,当允许破坏障碍T次时,每个位置事实上有T中情况,需要标记每种情况是否访问过。
@ # x # +
x # x # #
x # x # #
x x x # #
假设T=1,那么正确的路线的长度显然是10,在搜索过程中,我们可以选择破坏(1,2)的墙,到达(1,3),但是此时无法再破墙;沿着正确的路径走,会再次经过(1,3),但是此时的状态是与之前不可行时候的状态不一样,即用破墙次数来区分,因此为vis增加一个维度标记破墙次数即可。
import java.util.*;
class Pos{
public int x;
public int y;
public int t;
public Pos(int x,int y,int t) {
this.x=x;
this.y=y;
this.t=t;
}
}
public class Main{
public static int M;
public static int N;
public static int T;
public static char[][] G=new char[205][205];
public static int ans=0x3f3f3f3f;
public static int[] dx= {0,0,1,-1};
public static int[] dy= {1,-1,0,0};
public static boolean[][][] vis=new boolean[205][205][10];
public static int[][][] dis=new int[205][205][10];
public static void main(String[] Args) {
Scanner sc=new Scanner(System.in);
M=sc.nextInt();
N=sc.nextInt();
T=sc.nextInt();
sc.nextLine();//要吸收Enter
for(int i=0;i<205;i++) {
for(int j=0;j<205;j++) {
Arrays.fill(vis[i][j], false);
Arrays.fill(dis[i][j],0x3f3f3f3f);
}
}
Pos st=new Pos(0,0,0);
Pos dst=new Pos(0,0,0);
for(int i=0;i<M;i++) {
String tmp=sc.nextLine();
for(int j=0;j<N;j++) {
G[i][j]=tmp.charAt(j);
if(G[i][j]=='@') {
st=new Pos(i,j,T);
}else if(G[i][j]=='+') {
dst=new Pos(i,j,0);
}
}
}
LinkedList<Pos> q=new LinkedList<Pos>();
vis[st.x][st.y][st.t]=true;
Arrays.fill(dis[st.x][st.y],0);
q.addLast(st);
boolean flag=false;
while(!q.isEmpty()) {
Pos tmp=q.removeFirst();
for(int i=0;i<4;i++) {
int x=tmp.x+dx[i];
int y=tmp.y+dy[i];
int t=tmp.t;
if(x<0 || x>=M || y<0 || y>=N || vis[x][y][t]) {
continue;
}else if(G[x][y]=='+') {
dis[x][y][t]=dis[tmp.x][tmp.y][tmp.t]+1;
flag=true;
break;
}else if(G[x][y]=='*') {
vis[x][y][t]=true;
dis[x][y][t]=dis[tmp.x][tmp.y][tmp.t]+1;
q.addLast(new Pos(x,y,t));
}else if(G[x][y]=='#' && t>0) {
t-=1;
vis[x][y][t]=true;
dis[x][y][t]=dis[tmp.x][tmp.y][tmp.t]+1;
q.addLast(new Pos(x,y,t));
}
}
if(flag) {
break;
}
}
for(int i=0;i<10;i++) {
ans=Math.min(ans, dis[dst.x][dst.y][i]);
}
if(ans==0x3f3f3f3f) {
ans=-1;
}
System.out.print(ans);
}
}