每个输入包含 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次。
3 3 ... ... ... 0 1 4 1 0 0 1 -1 0 0 -1
3
import java.util.*; public class Main { public static void main(String[] args){ Scanner in = new Scanner(System.in); while (in.hasNext()) {//注意while处理多个case int x=in.nextInt(); int y=in.nextInt(); char[][] points=new char[x][y]; int[][] tar=new int[x][y]; for(int i=0;i<x;i++){ String str=in.next(); points[i]=str.toCharArray(); } int startx=in.nextInt(); int starty=in.nextInt(); int k=in.nextInt(); int[] stepx=new int[k]; int[] stepy=new int[k]; for(int i=0;i<k;i++){ stepx[i]=in.nextInt(); stepy[i]=in.nextInt(); } Queue<Integer> xqueue=new LinkedList<Integer>(); Queue<Integer> yqueue=new LinkedList<Integer>(); //引入队列是为了遍历到最后不能走为止 xqueue.add(startx); yqueue.add(starty); tar[startx][starty]=1; //起始点访问标记;1表示已经访问 while(!xqueue.isEmpty()&&!yqueue.isEmpty()){ startx=xqueue.remove(); //取队首 starty=yqueue.remove(); for(int i=0;i<k;i++){ if(startx+stepx[i]<x&&startx+stepx[i]>=0&&starty+stepy[i]<y&&starty+stepy[i]>=0) //不出界 if(tar[startx+stepx[i]][starty+stepy[i]]==0){ if(points[startx+stepx[i]][starty+stepy[i]]=='.'){ tar[startx+stepx[i]][starty+stepy[i]]=tar[startx][starty]+1; xqueue.add(startx+stepx[i]); yqueue.add(starty+stepy[i]); } else tar[startx+stepx[i]][starty+stepy[i]]=-1; //访问点为X } } } int max=0; int getRoad=1; for(int i=0;i<x;i++) for(int j=0;j<y;j++){ if(points[i][j]=='.'&&tar[i][j]==0){ getRoad=0; //有存在没有被访问的“.”说明不能遍历完全,有些出口到不了。 } max=Math.max(max, tar[i][j]); } if(getRoad==0) System.out.println(-1); else System.out.println(max-1); } } }
仔细读题可以发现 题目要求的就是从出发点宽度优先搜索不走回头路 能够到达的最远距离;
按测试样例为例
...
...
...
第0步为起点(0, 1)
第一步能够到达的点为(0, 0) (1, 1) (0, 2)
第二步能到达的点(去掉重复)为(1, 0) (2, 1) (1, 2)
第三步能到达的点为(2, 0) (2, 2)
此时第四部无论怎么走都会重复 所以最长步数为3
但是这种解法忽略了一种“孤岛的情况” 例如
X.X
...
XXX
X.X
此时选择最下面这个“.”即为最差情况 答案-1
因此在宽度优先搜索结束后要判断是否有孤岛存在
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
//常量区
const int maxn = 50 + 5;
int taken[maxn][maxn], n, m, k, sx[maxn], sy[maxn];
int x_0, y_0;
char ma[maxn][maxn];
queue<int> qx[maxn];
queue<int> qy[maxn];
//函数区
int bfs(){
qx[0].push(x_0); qy[0].push(y_0);
taken[x_0][y_0] = 1;
int d;
for(d = 0; ; d++){
while(!qx[d].empty()){
int tx = qx[d].front(); qx[d].pop();
int ty = qy[d].front(); qy[d].pop();
for(int i=0;i<k;i++){
if((tx+sx[i]>=0) && (tx+sx[i])<n && (ty+sy[i]>=0) && (ty+sy[i])<m &&
taken[tx+sx[i]][ty+sy[i]]==0 && ma[tx+sx[i]][ty+sy[i]] != 'X'){
qx[d+1].push(tx+sx[i]);
qy[d+1].push(ty+sy[i]);
taken[tx+sx[i]][ty+sy[i]] = 1;
}
}
}
if(qx[d+1].empty()) break;
}
return d;
}
//main函数
int main(){
scanf("%d%d", &n, &m);
for(int i=0;i<n;i++)
for(int j=0;j<m;j++) scanf(" %c", &ma[i][j]);
scanf("%d%d%d", &x_0, &y_0, &k);
for(int i=0;i<k;i++) scanf("%d%d", &sx[i], &sy[i]);
int ans = bfs(); //宽度优先搜索 返回可以行走的最长步数
//判断是否有孤岛 即无法访问到但是可通行的点
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(taken[i][j] == 0 && ma[i][j] == '.'){
printf("-1\n"); //若有孤岛 选择孤岛为终点 无法离开 此时是最坏情况
return 0;
}
if(ans == 0) cout<<-1<<endl;//只有起点可以走 其他都是'X'的情况
else cout<<ans<<endl;
return 0;
}
#include <iostream> #include <queue> #include <string.h> const int T = 50; char DL[T][T]; int n = 0; int m = 0; int x0 = 0; int y0 = 0; int k = 0; int dx[T]; int dy[T]; int visited[T][T]; //记录最短到达步数 int main() { std::cin >> n >> m; for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { std::cin >> DL[i][j]; } } std::cin >> x0 >> y0 >> k; for (int i = 0; i < k; ++i) { std::cin >> dx[i] >> dy[i]; } memset(visited, 0, sizeof(visited)); visited[x0][y0] = 1; //起始步数为1,0表示未访问 std::queue<std::pair<int, int> > q; q.push(std::pair<int, int>(x0, y0)); int curx = 0; int cury = 0; int nextx = 0; int nexty = 0; while (!q.empty()) { curx = q.front().first; cury = q.front().second; q.pop(); for (int j = 0; j < k; ++j) { nextx = curx + dx[j]; nexty = cury + dy[j]; if (nextx >= 0 && nextx < n && nexty >= 0 && nexty < m && visited[nextx][nexty] == 0) { if (DL[nextx][nexty] == '.') { visited[nextx][nexty] = visited[curx][cury] + 1; q.push(std::pair<int, int>(nextx, nexty)); } } } } int max = 0; for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { if (DL[i][j] == '.') { if (visited[i][j] == 0) { std::cout << -1; return 0; } else if (visited[i][j] > max) { max = visited[i][j]; } } } } std::cout << max-1; return 0; }
# coding: utf-8
'''
题意可以理解为:有没有可以通行的点,但牛牛到不了(输出-1)。如果没有这样的点,牛牛可能花费最多步数是多少。
思路:计算地图里,每个点的最短到达步数。找到到不了的点,或者步数最多的点。
1. 创建3个矩阵,size都是n*m的。分别是地图矩阵 mm、步数矩阵 sm、到达矩阵 am。详见代码里的注释。*也可以把3个矩阵放到一起。
2. 设置初始点为第一轮的探索点,更新 sm 里初始点的最短步数为0,更新 am 里初始点的到达状态为1。
3. 找到从探索点一步能到达的点,且这些点可以通行并没有到达过。更新这些点的 sm 和 am。并将这些点当作下一轮的探索点。
4. 循环第3步,直到没有新一轮的探索点了。
5. 从 sm 中可以得到正确答案。
'''
def main():
line_1 = raw_input().split()
n, m = int(line_1[0]), int(line_1[1])
map_matrix = [raw_input() for i in range(n)] # 地图矩阵,'.'表示可以通行,其他表示不可通行
line_2 = raw_input().split()
x0, y0 = int(line_2[0]), int(line_2[1]) # 开始点的坐标
k = input() # 共有k种行走方式
alternative_steps = [[int(s) for s in raw_input().split()] for i in range(k)] # 可以选择的行走方式
step_matrix = [[-1] * m for i in range(n)] # 步数矩阵,记录到达该点使用最短步数。初始是-1。
arrived_matrix = [[0] * m for i in range(n)] # 到达矩阵,记录是否已经到达过该点。初始是0,表示没有到达过,
# 判断初始点是否是可达点
if map_matrix[x0][y0] != '.':
return -1
# 初始点修改为已到达的点
arrived_matrix[x0][y0] = 1
# 初始点到达步数为0
step_matrix[x0][y0] = 0
current_points = [[x0, y0]] # 第一轮所在的探索点(多个)
while len(current_points) > 0: # 如果当前探索点是0个,结束循环。
next_points = [] # 下一轮的探索点(多个)
for point in current_points:
x, y = point[0], point[1] # 一个探索点
for step in alternative_steps:
x_, y_ = x + step[0], y + step[1] # 该探索点一步能到达的点
if x_ < 0 or x_ >= n or y_ < 0 or y_ >= m: # 检查是否越界
continue
if map_matrix[x_][y_] != '.' or arrived_matrix[x_][y_] == 1: # 检查该点是否可以通行,或者已经达到过
continue
else:
step_matrix[x_][y_] = step_matrix[x][y] + 1 # 更新步数矩阵
arrived_matrix[x_][y_] = 1 # 更新到达矩阵
next_points.append([x_, y_]) # 该点添加到下一轮探索点里。
current_points = next_points
# 从步数矩阵中找到到不了的点,或者最大的步数。输出
max_step = 0
for i in range(n):
for j in range(m):
step = step_matrix[i][j]
if step == -1 and map_matrix[i][j] == '.':
return -1
if step > max_step:
max_step = step
return max_step
print main()
import java.util.*; import java.io.*; public class Main { /** *关键描述:地牢的出口可能在任意某个可以通行的位置上。牛牛想知道最坏情况下,他需要多少步才可以离开这个地牢。 *这句话的意思是什么呢?结合示离,意思是在可通行的位置上,我们要选择最短路径。但是有多个可通行的位置上,我们要找最远的,若最远不可达输出-1 *这样问题就转化为最短路径问题,我们要找到最远点的最短路径。使用BFS可以实现。 */ public static void main(String[] args) throws Exception{ String[] arrInput; char[] arrChar; Deque<Pointer> deque = new ArrayDeque<Pointer>();//使用双端队列做队列 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); arrInput = br.readLine().trim().split(" "); int n = Integer.parseInt(arrInput[0]); int m = Integer.parseInt(arrInput[1]); int[][] arrDungeon = new int[n][m];//-1不可通行,0可以通行,整数为到达的步数 for (int i=0; i<n; i++) { arrChar = br.readLine().trim().toCharArray();//应为连续字符没有间隔,用toCharArray转化为字符数组 for (int j=0; j<m; j++) { if (arrChar[j] == '.') { arrDungeon[i][j] = 0; } else if (arrChar[j] == 'X') { arrDungeon[i][j] = -1; } } } arrInput = br.readLine().trim().split(" "); Pointer pointer = new Pointer(); pointer.x = Integer.parseInt(arrInput[0]); pointer.y = Integer.parseInt(arrInput[1]); int startxx = pointer.x; int startyy = pointer.y; deque.offerLast(pointer);//入队 int intStepCnt = Integer.parseInt(br.readLine().trim()); int[][] arrStep = new int[intStepCnt][2]; for (int i=0; i<intStepCnt; i++) { arrInput = br.readLine().trim().split(" "); arrStep[i][0] = Integer.parseInt(arrInput[0]); arrStep[i][1] = Integer.parseInt(arrInput[1]); } int x = 0; int y = 0; int x1 = 0; int y1 = 0; //BFS由近及远 while (deque.size() > 0) { Pointer pointerOne = deque.pollFirst(); x = pointerOne.x; y = pointerOne.y; for (int i=0; i<intStepCnt; i++) { x1 = x + arrStep[i][0]; y1 = y + arrStep[i][1]; if (x1 >= 0 && x1 < arrDungeon.length && y1 >= 0 && y1 < arrDungeon[0].length && arrDungeon[x1][y1] == 0) {//不越界的情况 arrDungeon[x1][y1] = arrDungeon[x][y] + 1; Pointer temp = new Pointer(); temp.x = x1; temp.y = y1; deque.offerLast(temp);//入队 } } } int max = 0; boolean isHaveCanNotAccessPointer = false;//标记有没有不可达点的 for (int i=0; i<n; i++) { if (isHaveCanNotAccessPointer == true) { break; } for (int j=0; j<m; j++) { if ((i != startxx || j != startyy) && arrDungeon[i][j] == 0) {//不是起点若是0就是有不可达点 isHaveCanNotAccessPointer = true; break; } if (arrDungeon[i][j] > max) { max = arrDungeon[i][j]; } } } if (isHaveCanNotAccessPointer) { System.out.println(-1); } else { System.out.println(max); } } static class Pointer {//坐标类 public int x; public int y; } }
import java.util.*; public class Main{ public static void main(String[] args){ Scanner input=new Scanner(System.in); while(input.hasNext()){ int n=input.nextInt(); int m=input.nextInt(); char[][] a=new char[n][m]; for(int i=0; i<n; i++){ a[i]=input.next().toCharArray(); } int x0=input.nextInt(); int y0=input.nextInt(); int k=input.nextInt(); int[] dx=new int[k]; int[] dy=new int[k]; for(int i=0; i<k; i++){ dx[i]=input.nextInt(); dy[i]=input.nextInt(); } int[][] f=new int[n][m]; ArrayList<Integer> x=new ArrayList<>(); ArrayList<Integer> y=new ArrayList<>(); x.add(x0); y.add(y0); f[x0][y0]=1; //起始点访问标记;1表示已经访问 while(!x.isEmpty() && !y.isEmpty()){ int tempX=x.remove(0); int tempY=y.remove(0); for(int i=0; i<k; i++){ if(tempX+dx[i]>=0&&tempX+dx[i]<n&&tempY+dy[i]>=0&&tempY+dy[i]<m){ //判断是否越界 if(f[tempX+dx[i]][tempY+dy[i]]==0){ if(a[tempX+dx[i]][tempY+dy[i]]=='.'){ f[tempX+dx[i]][tempY+dy[i]]=f[tempX][tempY]+1; x.add(tempX+dx[i]); y.add(tempY+dy[i]); }else{ f[tempX+dx[i]][tempY+dy[i]]=-1; } } } } } int max=0; int tt=1; for(int i=0; i<n; i++){ for(int j=0; j<m; j++){ if(f[i][j]==0 && a[i][j]=='.') tt=0; else{ max=Math.max(max, f[i][j]); } } } if(tt==1) System.out.println(max-1); else System.out.println(-1); } } }
import java.util.List; import java.util.Queue; import java.util.ArrayList; import java.util.LinkedList; import java.util.Scanner; public class Main{ public static void main(String[] args) { Scanner in = new Scanner(System.in); int n = in.nextInt(); int m = in.nextInt(); char[][] map = new char[n][m];//存这个地牢的信息 for(int i=0;i<n;i++){ map[i] = in.next().toCharArray(); } int startX = in.nextInt();//起点 int startY = in.nextInt(); int k = in.nextInt();//步子数 int[][] dir = new int[k][2];//神奇的步子 for(int i=0;i<k;i++){ dir[i][0] = in.nextInt(); dir[i][1] = in.nextInt(); } int[][] minThisPosition = new int[n][m];//到可行点的最小步数 for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ minThisPosition[i][j] = Integer.MAX_VALUE; } } minThisPosition[startX][startY] = 0; class Node{//局部内部类定义一个点 int x; int y; Node(int x, int y){ this.x = x; this.y = y; } public Node goK(int k){//尝试走第K种步子到达的节点 return new Node(x+dir[k][0],y+dir[k][1]); } public boolean isleagle(){//判断这个节点是不是在地牢内,是不是障碍 return x>=0&&y>=0&&x<n&&y<m&&map[x][y]=='.'; } } Node startNode = new Node(startX, startY); //用队列来记录是不是所有 "." 都被处理了 Queue<Node> queue = new LinkedList<>(); queue.add(startNode);//从起点开始 while(!queue.isEmpty()){ Node now = queue.poll(); for(int i=0;i<k;i++){ Node next = now.goK(i); if(next.isleagle()){ //这里避免了往回走,不加1也可以,就是大于等于minThisPosition[now.x][now.y]+1 if(minThisPosition[next.x][next.y]>minThisPosition[now.x][now.y]+1){ //每种步子都尝试一下,找到最小值 minThisPosition[next.x][next.y]=minThisPosition[now.x][now.y]+1; queue.add(next);//加到队列里等待处理 } } } } int result = 0; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ //找到最大值 if(map[i][j] == '.') result = Math.max(result, minThisPosition[i][j]); } } //如果存在不能到达的 "." ,就会保留原来的初试值,返回-1 System.out.println(result == Integer.MAX_VALUE?-1:result ); } }
#include<stdio.h> #include<queue> #include<string.h> using namespace std; #define max(a,b) a>b?a:b int Next[50][2],step[50][50],book[50][50],n,m,s,e,k,i,j,Max=-1; char Map[50][50]; struct node{ int x,y; node(int x,int y):x(x),y(y){} }; int main(){ memset(step,-1,sizeof(step)); for(scanf("%d%d",&n,&m),i=0;i<n;i++) scanf("%s",Map[i]); for(scanf("%d%d%d",&s,&e,&k),i=0;i<k;i++) scanf("%d%d",&Next[i][0],&Next[i][1]); queue<node> Q; Q.push(node(s,e)),book[s][e]=1,step[s][e]=0; while(!Q.empty()){ node head=Q.front();Q.pop(); for(i=0;i<k;i++){ int nx=head.x+Next[i][0],ny=head.y+Next[i][1]; if(nx<0||nx>=n||ny<0||ny>=m||book[nx][ny]||Map[nx][ny]!='.') continue; book[nx][ny]=1,step[nx][ny]=step[head.x][head.y]+1,Q.push(node(nx,ny)); } } for(k=1,i=0;i<n;i++) for(j=0;j<m;j++) Map[i][j]=='.'?step[i][j]>=0?Max=max(Max,step[i][j]):k=0:Max=Max; printf("%d\n",Max>0&&k?Max:-1); }
import java.io.*; import java.util.*; public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String[] params = br.readLine().split(" "); int n = Integer.parseInt(params[0]), m = Integer.parseInt(params[1]); char[][] grid = new char[n][]; for(int i = 0; i < n; i++){ grid[i] = br.readLine().toCharArray(); } params = br.readLine().split(" "); int x0 = Integer.parseInt(params[0]), y0 = Integer.parseInt(params[1]); int k = Integer.parseInt(br.readLine()); int[] dx = new int[k], dy = new int[k]; for(int i = 0; i < k; i++){ params = br.readLine().split(" "); dx[i] = Integer.parseInt(params[0]); dy[i] = Integer.parseInt(params[1]); } int maxStep = 0; int[][] dis = bfs(grid, x0, y0, dx, dy); for(int i = 0; i < n; i++){ for(int j = 0; j < m; j++){ if(grid[i][j] == '.'){ // 所有能走的地方都可以作为出口 maxStep = Math.max(maxStep, dis[i][j]); } } } System.out.println(maxStep == Integer.MAX_VALUE? -1: maxStep); } private static int[][] bfs(char[][] grid, int x0, int y0, int[] dx, int[] dy) { int n = grid.length, m = grid[0].length; int[][] dis = new int[n][m]; for(int i = 0; i < n; i++){ for(int j = 0; j < m; j++){ dis[i][j] = Integer.MAX_VALUE; } } Queue<int[]> queue = new LinkedList<>(); queue.offer(new int[]{x0, y0}); dis[x0][y0] = 0; while(!queue.isEmpty()){ int queueSize = queue.size(); for(int j = 0; j < queueSize; j++){ int[] cur = queue.poll(); int x = cur[0], y = cur[1]; for(int i = 0; i < dx.length; i++){ int x_ = cur[0] + dx[i]; int y_ = cur[1] + dy[i]; if(0 <= x_ && x_ < n && 0 <= y_ && y_ < m && grid[x_][y_] == '.'){ if(dis[x_][y_] > dis[x][y] + 1){ // 类似迪杰斯特拉算法,距离变小了就更新 dis[x_][y_] = dis[x][y] + 1; queue.offer(new int[]{x_, y_}); } } } } } return dis; } }
//广度优先搜索 #include <iostream> #include <vector> #include <queue> using namespace std; typedef struct loc { int x, y; char val; bool visited; }loc; int bfs_map(vector<loc> & map, const int N, const int M, const int xStart, const int yStart, const int numSteps, const vector<int> steps); int main() { int n, m; cin >> n >> m; vector<loc> map; { loc c; for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { cin >> c.val; c.visited = false; c.x = i; c.y = j; map.push_back(c); } } } int x0, y0; cin >> x0 >> y0; int k; cin >> k; vector<int> steps; { int temp; for (int i = 0; i < k*2; ++i) { cin >> temp; steps.push_back(temp); } } int result = bfs_map(map, n, m, x0, y0, k, steps); cout << result << endl; return 0; } int bfs_map(vector<loc> & map, const int N, const int M, const int xStart, const int yStart, const int numSteps, const vector<int> steps){ int result = -1; //实际上计算广度优先搜索的层数 map[xStart * M + yStart].visited = true; queue<loc> Q, Q_temp; Q.push(map[xStart * M + yStart]); while (!Q.empty()) { result++; while (!Q.empty()) { loc currentLoc = Q.front(); Q.pop(); for (int i = 0; i < numSteps; ++i) { int xNew = currentLoc.x + steps[2 * i]; int yNew = currentLoc.y + steps[2 * i + 1]; if (xNew >= 0 && xNew < N && yNew >= 0 && yNew < M && map[xNew * M + yNew].val == '.' && map[xNew * M + yNew].visited == false) { map[xNew * M + yNew].visited = true; Q_temp.push(map[xNew * M + yNew]); } } } swap(Q, Q_temp); } //永远不可能出去的情况 for (int i = 0; i < N*M; ++i) { if (map[i].val == '.' && map[i].visited != true) return -1; } if (result > 0) return result; else return - 1; }
#include <iostream> #include <vector> #include <queue> using namespace std; struct Pos { int x; int y; int step; }; int m, n; bool ok(int x, int y, vector<vector<char>> &v) { if (x >= 0 && x<m && y>= 0 && y<n && v[x][y]=='.') return true; return false; } int main() { cin >> m >> n; vector<vector<char>> v(m, vector<char>(n)); for (int i = 0; i<m; i++) { for (int j = 0; j<n; j++) { cin >> v[i][j]; } } int x0, y0; cin >> x0 >> y0; int stepN; cin >> stepN; vector<vector<int>> move(stepN, vector<int>(2)); vector<vector<int>> vRes(m, vector<int>(n, 9999)); for (int i = 0; i<stepN; i++) { cin >> move[i][0] >> move[i][1]; } queue<Pos> qu; vRes[x0][y0] = 0; Pos start = { x0,y0,0 }; qu.push(start); Pos now,tmp; int x, y; while (!qu.empty()) { now = qu.front(); qu.pop(); for (int i = 0; i<stepN; i++) { x = now.x + move[i][0]; y = now.y + move[i][1]; if (ok(x, y, v) && now.step+1<vRes[x][y]) { vRes[x][y] = now.step + 1; tmp = { x,y,now.step + 1 }; qu.push(tmp); } else { continue; } } } int maxStep = 0; for (int i = 0; i<m; i++) { for (int j = 0; j<n; j++) { if (vRes[i][j]>maxStep && v[i][j]=='.') maxStep = vRes[i][j]; } } maxStep = (maxStep == 9999) ? -1 : maxStep; cout << maxStep << endl; return 0; }
#-*- coding: utf8 -*- class cell: def __init__(self,x,y,steps): self.x=x self.y=y self.steps=steps def check(matrix,visited,x,y,n,m): return (0<=x<n and 0<=y<m) and (matrix[x][y]=='.') and visited[x][y]==False def maze(matrix,n,m,x,y,stepxy): """ 最短路径bfs,最坏的情况下需要多少步逃脱,出口不定,找最短路径中最长的路径长 """ q=[] q.append(cell(x,y,0)) visited=[[False]*m for _ in range(n)] visited[x][y]=True maxsteps=0 while len(q)!=0: elem=q.pop(0) maxsteps=max(maxsteps,elem.steps) for vx,vy in stepxy: newx=elem.x+vx newy=elem.y+vy if check(matrix,visited,newx,newy,n,m): q.append(cell(newx,newy,elem.steps+1)) visited[newx][newy]=True for i in range(n): for j in range(m): if matrix[i][j]=='.' and visited[i][j]==False: return -1 return maxsteps n,m=map(int,raw_input().strip().split(' ')) matrix=[list(raw_input().strip()) for _ in range(n)] x0,y0=map(int,raw_input().strip().split(' ')) steps=input() stepxy=[map(int,raw_input().strip().split(' ')) for _ in range(steps)] print maze(matrix,n,m,x0,y0,stepxy)
# -*- coding:utf-8 -*- n, m = map(int, raw_input().split()) A, d = [[0] * m for _ in range(n)], 0 for i in range(n): A.append([0] * m) s1 = raw_input() for j in range(len(s1)): if s1[j] == 'X': A[i][j], d = -1, d + 1 s, d = 0, m * n - d x, y = map(int, raw_input().split()) k = int(raw_input()) q, dirs = [], [] q.append([x, y, 0]) for i in range(k): dirs.append(map(int, raw_input().split())) while q: x0, y0, p = q.pop(0) if A[x0][y0] != 0: continue A[x0][y0], d = p + 1, d - 1 s = max(A[x0][y0], s) for k in dirs: x, y = x0 + k[0], y0 + k[1] if (0 <= x < n and 0 <= y < m) and A[x][y] == 0: q.append([x, y, A[x0][y0]]) print s - 1 if d == 0 else -1
#include <bits/stdc++.h> using namespace std; int N, M; vector<vector<char>> rec; struct Position { int x; int y; Position(int x_, int y_) :x(x_), y(y_) {} bool isOK() { return 0 <= x && x < N && 0 <= y && y < M && rec[x][y] == '.'; } Position add(Position p) { return Position(x + p.x, y + p.y); } }; int main() { while (cin >> N >> M) { for (int i = 0; i < N; ++i) { vector<char> temp(M,0); for (int j = 0; j < M; ++j) cin >> temp[j]; rec.push_back(temp); } int x0, y0; cin >> x0 >> y0; int K; cin >> K; vector<Position>pos; for (int i = 0; i<K; ++i) { int x, y; cin >> x >> y; pos.emplace_back(x, y); } Position init(x0, y0); // queue<Position> que; que.push(init); int step[50][50]; for (int i = 0; i < 50; ++i) for (int j = 0; j < 50; ++j) step[i][j]= 100; step[x0][y0] = 0; while (!que.empty()) { auto now = que.front(); que.pop(); for (int i = 0; i < K; ++i) { auto next = now.add(pos[i]); if (next.isOK() && step[next.x][next.y]>step[now.x][now.y] + 1) { step[next.x][next.y] = step[now.x][now.y] + 1; que.push(next); } } } int ma=0; for (int i = 0; i < N; ++i) { for (int j = 0; j < M; ++j) { if (rec[i][j] == '.') ma = max(ma, step[i][j]); } } cout << ((ma == 100) ? -1 : ma) << std::endl; // } return 0; }
#include <iostream> #include <numeric> #include <algorithm> #include <string> #include <set> using namespace std; class point{ public: int x; int y; }; int m,n; int a[51][51];//地图 int x,y,k; point p[51]; int fun() { int flag; while(1){ flag=0; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(a[i][j]!=-1&&a[i][j]!=999999){ for(int l=1;l<=k;l++){ int xx=i+p[l].x; int yy=j+p[l].y; if(xx>n||xx<=0||yy>m||yy<=0)continue; if(a[xx][yy]==-1)continue; if((a[xx][yy])>(a[i][j]+1)){ a[xx][yy]=a[i][j]+1; flag=1; } } } } } if(flag==0) break; } //cout<<a[2][3]<<endl; int res=0; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(a[i][j]==999999)return -1; if(a[i][j]==-1)continue; if(res<a[i][j]) res=a[i][j]; } } return res; } int main() { cin>>n>>m; char c; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ cin>>c; if(c=='.') a[i][j]=999999; else a[i][j]=-1; } } cin>>x>>y>>k; for(int i=1;i<=k;i++) cin>>p[i].x>>p[i].y; a[x+1][y+1]=0; cout<<fun()<<endl; return 0; }
BFS,就是代码稍微多一点点。 #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <vector> #include <queue> using namespace std; const int maxn = 52; char maze[maxn][maxn]; int cnt[maxn][maxn]; int n, m; int k; //x0被编译器占用, 所以用x00 int x00, y00; vector<pair<int, int> > steps; struct node { int x, y; int stepNum; }; bool ok(int x, int y) { if(x >= 0 && x < n && y >= 0 && y < m) return true; return false; } int BFS() { for(int i = 0; i < n; i++) { for(int j = 0; j < m; j++) { //-1代表未访问 cnt[i][j] = -1; } } queue<node> que; node tmp; tmp.x = x00; tmp.y = y00; tmp.stepNum = 0; cnt[x00][y00] = 0; que.push(tmp); while(!que.empty()) { node u = que.front(); que.pop(); int newx, newy; for(int i = 0; i < (int)steps.size(); i++) { newx = u.x + steps[i].first; newy = u.y + steps[i].second; if(!ok(newx, newy)) continue; //遇到不可以走的地方 else if(maze[newx][newy] == 'X') cnt[newx][newy] = -2; else { //说明已经访问过 if(cnt[newx][newy] != -1) continue; ///visited //没有访问过 else { cnt[newx][newy] = u.stepNum + 1; tmp.x = newx; tmp.y = newy; tmp.stepNum = u.stepNum + 1; que.push(tmp); } } } } int maxValue = -1; for(int i = 0; i < n; i++) { for(int j = 0; j < m; j++) { if(maze[i][j] == 'X') continue; else if(maze[i][j]=='.' && cnt[i][j] == -1) return -1; maxValue = max(maxValue, cnt[i][j]); } } return maxValue; } int main() { while(scanf("%d%d", &n, &m) != EOF) { getchar(); for(int i = 0; i < n; i++) { scanf("%s", maze[i]); } scanf("%d%d", &x00, &y00); scanf("%d", &k); pair<int, int> read; steps.clear(); for(int i = 0; i < k; i++) { scanf("%d%d", &read.first, &read.second); steps.push_back(read); } int res = BFS(); printf("%d\n", res); } return 0; }
#include <iostream> #include <cstdio> #include <cstdlib> #include <string> #include <climits> #include <algorithm> #include <queue> using namespace std; int n,m,d[55][2]; string g[55]; struct Point { int x,y; Point(){} Point(int xx, int yy):x(xx),y(yy){} Point go(int index){ return Point(x+d[index][0], y+d[index][1]); } bool isAvailable(){ return x>=0 && y>=0 && x<n && y<m && g[x][y]=='.'; } }; int main() { int dist[55][55]; int cnt; cin>>n>>m; for(int i=0;i<n;i++) cin>>g[i]; Point s; cin>>s.x>>s.y; cin>>cnt; for(int i=0;i<cnt;i++) cin>>d[i][0]>>d[i][1]; fill(dist[0], dist[54]+55, INT_MAX); dist[s.x][s.y] = 0; queue<Point> q; q.push(s); while(!q.empty()) { Point a = q.front(); q.pop(); for(int i=0;i<cnt;i++) { Point b = a.go(i); if(b.isAvailable()) if(dist[b.x][b.y] > dist[a.x][a.y]+1) { dist[b.x][b.y] = dist[a.x][a.y]+1; q.push(b); } } } int result = 0; for(int i=0;i<n;i++) for(int j=0;j<m;j++) if(g[i][j]=='.') result = max(result, dist[i][j]); cout<<(result==INT_MAX?-1:result)<<endl; return 0; }