网易_地牢逃脱
题目描述
给定一个 n 行 m 列的地牢,其中 '.' 表示可以通行的位置,'X' 表示不可通行的障碍,牛牛从 (x0 , y0 ) 位置出发,遍历这个地牢,和一般的游戏所不同的是,他每一步只能按照一些指定的步长遍历地牢,要求每一步都不可以超过地牢的边界,也不能到达障碍上。地牢的出口可能在任意某个可以通行的位置上。牛牛想知道最坏情况下,他需要多少步才可以离开这个地牢。
输入描述:
每个输入包含 1 个测试用例。每个测试用例的第一行包含两个整数 n 和 m(1 <= n, m <= 50),表示地牢的长和宽。接下来的 n 行,每行 m 个字符,描述地牢,地牢将至少包含两个 '.'。接下来的一行,包含两个整数 x0, y0,表示牛牛的出发位置(0 <= x0 < n, 0 <= y0 < m,左上角的坐标为 (0, 0),出发位置一定是 '.')。之后的一行包含一个整数 k(0 < k <= 50)表示牛牛合法的步长数,接下来的 k 行,每行两个整数 dx, dy 表示每次可选择移动的行和列步长(-50 <= dx, dy <= 50)
输出描述:
输出一行一个数字表示最坏情况下需要多少次移动可以离开地牢,如果永远无法离开,输出 -1。以下测试用例中,牛牛可以上下左右移动,在所有可通行的位置.上,地牢出口如果被设置在右下角,牛牛想离开需要移动的次数最多,为3次。
示例1
输入
3 3
...
...
...
0 1
4
1 0
0 1
-1 0
0 -1
输出
3
题意:
这道题主要是理解题意,开始完全没看懂,后来看了看大佬的分析,才明白怎么回事
题目先是输入迷宫的参数,然后起点位置,然后k种走的方法,每一步都得在这k种走法中找。题目说:地牢的出口可能在任意某个可以通行的位置上。牛牛想知道最坏情况下,他需要多少步才可以离开这个地牢。意思是出口可以再任何一个位置,然后找到这个位置走的最短步数,然后从这些最短步数中找最大值。
做法:最容易的是用bfs,直接寻找从起点开始算可以走的最长步数,每走一个点就标记已经走过,最后输出最大值就行。但是请注意,题目说的是出口可以在任意一个位置的最坏情况。那么当有一个点为“.”时,而且没法到达这个点,那么结果输出为-1
import java.util.*;
public class Main {
public static int dx[]=new int[52];
public static int dy[]=new int[52];
public static int m;
public static int n;
public static void main(String args[]) {
int i,j,k,d;
int a,b;
Scanner cin=new Scanner(System.in);
int start;
while(cin.hasNextInt()) {
n=cin.nextInt();
m=cin.nextInt();
char[][]mmap=new char[n][m];
int[][]vis=new int[n][m];
for(i=0;i<n;i++){
mmap[i]=cin.next().toCharArray();
}
int startx=cin.nextInt();
int starty=cin.nextInt();
k=cin.nextInt();
//System.out.println(k);
for(j=0;j<k;j++)
{
dx[j]=cin.nextInt();
dy[j]=cin.nextInt();
}
class Node{
int x;
int y;
Node(int x, int y){
this.x = x;
this.y = y;
}
public Node getK(int k){//尝试走第K种步子到达的节点
return new Node(x+dx[k],y+dy[k]);
}
public boolean isleagle(){//判断这个节点是不是在地牢内,是不是障碍
return x>=0&&y>=0&&x<n&&y<m&&mmap[x][y]=='.';
}
}
Queue<Node>que=new LinkedList();
while(!que.isEmpty())
{
que.poll();
}
vis[startx][starty]=1;
Node startPoint=new Node(startx,starty);
Node tmp,newPoint;
que.add(startPoint);
while(!que.isEmpty())
{
tmp=que.poll();
// System.out.printf("%d %d\n",tmp.x,tmp.y);
for(i=0;i<k;i++){
newPoint=tmp.getK(i);
if(newPoint.isleagle()&&(vis[newPoint.x][newPoint.y]==0)){
vis[newPoint.x][newPoint.y]=vis[tmp.x][tmp.y]+1;
que.add(newPoint);
}
}
}
int ans=0;
int flag=0;
for(i=0;i<n;++i){
for(j=0;j<m;++j)
{
if(mmap[i][j]=='.'&&vis[i][j]==0)flag=1;
ans=Math.max(ans, vis[i][j]);
}
if(flag>0)break;
}
// for(i=0;i<n;++i){
//
// for(j=0;j<m;++j)
// System.out.printf("%d ",vis[i][j]);
// System.out.println();
// }
if(flag>0)System.out.println(-1);
else
{
if(ans!=1)System.out.println(ans-1);
else System.out.println(-1);
}
}
}
}
/*
4 3
X.X
...
XXX
X.X
0 1
4
1 0
0 1
-1 0
0 -1
*/