//注:该代码,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; }