用一个整形矩阵matrix表示一个网格,1代表有路,0代表无路,每一个位置只要不越界,都有上下左右四个方向,求从最左上角到右下角的最短通路值
例如,matrix为:
1 0 1 1 1
1 0 1 0 1
1 1 1 0 1
0 0 0 0 1
通路只有一条,由12个1构成,所以返回12
[要求]
时间复杂度为
,空间复杂度为
第一行两个整数N,M表示矩形的长宽
接下来N行,每行一个长度为M的字符串表示矩形
输出一个整数表示最小步数
若从(1, 1)无法到达(n, m)请输出-1
4 5 10111 10101 11101 00001
12
4 5 11011 11111 11111 00001
8
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Queue;
import java.util.LinkedList;
public class Main {
static int[] dx = new int[]{1, -1, 0, 0};
static int[] dy = new int[]{0, 0, 1, -1};
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]);
Queue<int[]> queue = new LinkedList<>();
char[][] grid = new char[n][m];
boolean[][] visited = new boolean[n][m];
for(int i = 0; i < n; i++){
grid[i] = br.readLine().toCharArray();
if(grid[0][0] == '0'){
System.out.println(-1);
return;
}
}
queue.offer(new int[]{0, 0});
int steps = 0;
loop: while(!queue.isEmpty()){
steps ++;
int queueSize = queue.size();
// 下一步要走的位置都在队列中
for(int k = 0; k < queueSize; k++){
int[] pos = queue.poll();
if(pos[0] == n - 1 && pos[1] == m - 1) break loop; // 到达终点,退出BFS
visited[pos[0]][pos[1]] = true;
// 四个方向走动
for(int i = 0; i < 4; i++){
int x = pos[0] + dx[i];
int y = pos[1] + dy[i];
if(0 <= x && x < n && 0 <= y && y < m && grid[x][y] == '1' && !visited[x][y]) queue.offer(new int[]{x, y});
}
}
}
System.out.println(steps == 0? -1: steps);
}
} 但是这个题吧,有点醉,一模一样的思路Java会超时,C++就给我过了# include <bits/stdc++.h>
using namespace std;
vector<int> dx = {-1, 1, 0, 0};
vector<int> dy = {0, 0, 1, -1};
int BFS(int n, int m, vector<vector<char>> grid){
bool visited[n][m];
memset(visited, false, sizeof(visited));
queue<vector<int>> q;
q.push(vector<int>(2));
int steps = 0;
while(!q.empty()){
steps ++;
int queueSize = q.size();
for(int k = 0; k < queueSize; k++){
vector<int> cur = q.front();
q.pop();
if(cur[0] == n - 1 && cur[1] == m - 1) return steps;
for(int i = 0; i < 4; 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] == '1' && !visited[x][y]){
q.push({x, y});
visited[x][y] = true;
}
}
}
}
return -1;
}
int main(){
int n,m;
cin >> n >> m;
vector<vector<char>> grid(n, vector<char>(m));
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++)
cin >> grid[i][j];
}
cout << BFS(n, m, grid) << endl;
return 0;
}
//注:该代码,N和M与题目中的顺序相反
#include<iostream>
#include<vector>
using namespace std;
typedef struct//节点
{
int x;
int y;
}node;
int dx[4] = { 1,-1,0,0 };//用于判断上下左右时使用
int dy[4] = { 0,0,1,-1 };//同上
int main()
{
int M, N;
cin >> M >> N;
vector<vector<char>> m(M);//用于储存矩阵
vector<vector<int>> num(M);//用于储存走到矩阵各点的距离
for (int x = 0; x < M; x++)//扩容
{
m[x].resize(N);
num[x].resize(N);
}
for (int x = 0; x < M; x++)//输入矩阵元素
{
getchar();
for (int y = 0; y < N; y++)
{
scanf("%c", &m[x][y]);
}
}
num[0][0] = 1;//走到0,0坐标默认为1
m[0][0] = '0';//将0,0坐标的元素变'0',以免再次被查找
int flag = 1;//用于判断是否走到了右下角的点
node t = { 0,0 };
vector<node>q;//用于保存路上走到的点的坐标
q.push_back(t);//将0,0点存到路径动态数组
while (q.size())//当数组中没有元素时代表没路可走,即停止
{
t = q[0];//保存第一个点,以此点开始查找周围
q.erase(q.begin());//将第一个点从数组中去除,以免下次被调用
if (t.x == M - 1 && t.y == N - 1)//如果当前的点是右下角的点,就直接输出当前num矩阵中该点的数即可,第一次走到定为最小
{
flag = 0;//将flag变0,代表已走到
cout << num[M - 1][N - 1];
break;
}
for (int i = 0; i < 4; i++)//上下左右查找为'1'的点
{
int _x = t.x + dx[i];
int _y = t.y + dy[i];
if (_x < 0 || _x >= M || _y < 0 || _y >= N)//坐标越界跳过,执行下一次循环
{
continue;
}
if (m[_x][_y] == '1')//找到为'1'的点
{
m[_x][_y] = '0';//将该点变为'0'防止下次被查找
num[_x][_y] = num[t.x][t.y] + 1;//令该点对应的num的数变为前一个点的+1
node new_t = { _x,_y };
q.push_back(new_t);//因为该坐标可走,所以将新的坐标保存到数组中,做下次查找
}
}
}
if (flag)//如果找到右下角得点,不能输出,反之输出-1
{
cout << -1;
}
return 0;
} #include <bits/stdc++.h>
using namespace std;
char G[1001][1001];
int dir[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};
struct P{
int x, y, t;
};
int BFS(int n, int m){
bool vis[n+1][m+1];
memset(vis, false, sizeof(vis));
vis[1][1] = true;
queue<P> q;
q.push(P{1,1,1});
while(!q.empty()){
P p = q.front();
q.pop();
if(p.x==n && p.y==m)
return p.t;
for(int i=0;i<4;i++){
int xx = p.x + dir[i][0];
int yy = p.y + dir[i][1];
int tt = p.t + 1;
if(xx>=1 && xx<=n && yy>=1 && yy<=m && G[xx][yy]=='1' && !vis[xx][yy]){
q.push(P{xx, yy, tt});
vis[xx][yy] = true;
}
}
}
return -1;
}
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>G[i][j];
cout<<BFS(n,m)<<endl;
return 0;
} #include <bits/stdc++.h>
using namespace std;
// 一定要用char
int bfs(vector<vector<char>>& matrix, int n, int m){
queue<pair<int, int>> qu;
qu.push({1, 1});
int res = 0;
while(!qu.empty()){
int size = qu.size();
res++;
while(size--){
auto cur = qu.front();
qu.pop();
int x = cur.first, y = cur.second;
if(x == n && y == m){
return res;
}
if(x - 1 >= 1 && matrix[x - 1][y] == '1'){
matrix[x - 1][y] = '0';
qu.push({x - 1, y});
}
if(x + 1 <= n && matrix[x + 1][y] == '1'){
matrix[x + 1][y] = '0';
qu.push({x + 1, y});
}
if(y - 1 >= 1 && matrix[x][y - 1] == '1'){
matrix[x][y - 1] = '0';
qu.push({x, y - 1});
}
if(y + 1 <= m && matrix[x][y + 1] == '1'){
matrix[x][y + 1] = '0';
qu.push({x, y + 1});
}
}
}
return -1;
}
int main()
{
int n, m;
cin >> n >> m;
// 用 char 作为输入
vector<vector<char>> matrix(n + 1, vector<char>(m + 1));
for(int i = 1; i <= n; ++i){
for(int j = 1; j <= m; ++j){
cin >> matrix[i][j];
}
}
cout << bfs(matrix, n, m);
return 0;
} #include <stdio.h>
#include <stdlib.h>
#define not !
typedef struct Coordintate {
int x;
int y;
} Coord;
// function prototype
void printGrid(int* *grid, const int kRows, const int kCols);
int breadth_first_search_algorithm(int* *grid, const int kRows, const int kCols);
int main(const int argc, const char* const argv[]) {
int m, n;
fscanf(stdin, "%d %d\n", &m, &n);
int grid[m][n]; // 逻辑上两维的, 但在内存布局中二维数组是按一维线性连续存储的。
int x, y;
char str[n + 1];
for (y = 0; y < m ; ++y) {
gets(str);
for (x = 0; x < n; ++x)
*(*(grid + y) + x) = *(str + x) - 48;
}
int* rows_of_grid[m]; // 行指针
for (y = 0; y < m; ++y)
*(rows_of_grid + y) = grid + y;
// printGrid(rows_of_grid, m, n);
fprintf(stdout, "%d", breadth_first_search_algorithm(rows_of_grid, m, n));
return 0;
}
int breadth_first_search_algorithm(int* *grid, const int kRows, const int kCols) {
Coord q[kRows * kCols]; // 队列的大小由算法的时简复杂度决定,每个单位格最多入队出队一次!
int front = 0, rear = 0;
*(q + rear++) = (Coord) {.x = 0, .y = 0};
**grid = 0; // mark as visited
static const int dirs[] = { 0, -1, 0, 1, 0 };
Coord coord;
int i, x, y, nx, ny, steps = 0;
while (front < rear) {
size_t s = rear - front;
while (s--) {
coord = *(q + front++);
x = coord.x, y = coord.y;
if (x == kCols - 1 && y == kRows - 1)
return steps + 1;
for (i = 0; i < 4; ++i) {
nx = x + *(dirs + i), ny = y + *(dirs + i + 1);
if (nx < 0 || ny < 0 || nx == kCols || ny == kRows || !*(*(grid + ny) + nx))
continue;
*(q + rear++) = (Coord) {.x = nx, .y = ny};
*(*(grid + ny) + nx) = 0; // mark as visited
}
}
++steps;
}
return -1;
}
void printGrid(int* *grid, const int kRows, const int kCols) {
int x, y;
for (y = 0; y < kRows; ++y) {
for (x = 0; x < kCols; ++x)
printf("%d ", *(*(grid + y) + x));
fputc(10, stdout);
}
} Java BFS
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Main {
private static int m ;
private static int n ;
private static int[][] mat;
public static void main(String[] args) {
int[][] direcion = {{1,0},{0,1},{-1,0},{0,-1}};
int res = - 1;
Scanner sc = new Scanner(System.in);
m = sc.nextInt();
n = sc.nextInt();
mat = new int[m][n];
for (int i = 0; i < m; i++) {
String s = sc.next();
for (int j = 0; j < n; j++) {
mat[i][j] = s.charAt(j) -'0';
}
}
Queue<Node> queue = new LinkedList<>();
Node root = new Node(0,0,1);
queue.offer(root);
while(!queue.isEmpty()){
Node p = queue.peek();
int x = p.x;
int y = p.y;
int dis = p.dis;
if(x == m-1 && y == n - 1){
res = dis;
break;
}
for (int i = 0; i < direcion.length; i++) {
int newX = direcion[i][0] + x;
int newY = direcion[i][1] + y;
Node temp = new Node(newX,newY,dis+1);
if(isTrue(temp)){
queue.offer(temp);
mat[newX][newY] = 0;
}
}
queue.poll();
}
System.out.println(res);
}
public static class Node{
private int x;
private int y;
private int dis;
public Node(int x, int y, int dis) {
this.x = x;
this.y = y;
this.dis = dis;
}
}
public static boolean isTrue(Node node){
int x = node.x;
int y = node.y;
if((x<0 || x>=m)||(y<0 || y>=n)) return false;
if(mat[x][y] == 0) return false;
return true;
}
}
# -*- coding: utf-8 -*-
# !/usr/bin/python3
# 解题思路,利用广度优先搜索(BFS)进行遍历,从00到mn位置最少需要几层,就是最短路径的长度
# 判断每层的条件:下标合法不越界,数组中值为1,并且没有被遍历过
# BFS将每层可遍历的元素保存到一个集合中,将该集合作为下次遍历的对象,寻找下一层
# 只到找到mn位置为止,如果找不到就是-1
def bfs(arr, m, n):
if arr[0][0] == 0:
return -1
vst = [[0 for k in range(n)] for k in range(m)]
qe, steps, vst[0][0] = {(0, 0)}, 1, 1
while qe:
tmp = set()
for x, y in qe:
if (x, y) == (m - 1, n - 1):
return steps
for k, l in ((x - 1, y), (x, y + 1), (x + 1, y), (x, y - 1)):
if 0 <= k < m and 0 <= l < n and arr[k][l] == 1 and vst[k][l] == 0:
tmp.add((k, l))
vst[k][l] = 1
steps += 1
qe = tmp
return -1
while True:
try:
m, n = map(int, input().split())
arr = []
for i in range(m):
s = input()
tmp = []
for j in range(n):
tmp.append(int(s[j]))
arr.append(tmp)
print(bfs(arr, m, n))
except:
break