ToB企服应用市场:ToB评测及商务社交产业平台

标题: 逐日“亿“题 东方博宜OJ 1411 - 迷宫的路径 [打印本页]

作者: 天空闲话    时间: 2024-12-12 18:42
标题: 逐日“亿“题 东方博宜OJ 1411 - 迷宫的路径
原题链接:1411 - 迷宫的路径-东方博宜OJ

标题描述

Mitch老鼠在森林里嬉戏,不小心走进了一个迷宫内里,这个迷宫是一个 n 行 m 列的矩阵,迷宫中有些格子是可以走的,有些格子是不能走的,能走的格子用 o (小写字母 o )表现,不能走的格子用 # 表现。
Mitch选择走出迷宫的计谋是:先向右,如果右边走不通则选择向下,如果下边走不通则选择向左,如果左边走不通则选择向上;如果四个方向都走不通,则后退选择其他能走的路径。
Mitch从类似下图所示的迷宫的左上角
点进入迷宫(请注意:入口
 和出口的 
点都不是 # ),叨教Mitch有哪些方法可以走出迷宫,走到(n,m) 点;请编程求出所有大概的路径,输出这些路径,如果不存在任何的路径可以走出迷宫,请输出 no。


输入
第一行包含两个整数 n 和 m ,中间用单个空格隔开,代表迷宫的行和列的数目。
接下来 n 行,每行 m 个字符,描述迷宫舆图。字符只有o 或 # 两种,o 代表这个格子可以走,# 代表这个格子不能走。(4≤n,m≤10 )
输出
请按照Mitch选择的走出迷宫的计谋,输出所有大概的路径,输出形式请参考样例输出的形式。
如果不存在任何的路径可以走出迷宫,请输出 no。
样例
输入

  1. 6 5
  2. ooooo
  3. o####
  4. ooooo
  5. #oo#o
  6. oooo#
  7. o#ooo
复制代码
输出

  1. 1:1,1->2,1->3,1->3,2->3,3->4,3->5,3->5,4->6,4->6,5
  2. 2:1,1->2,1->3,1->3,2->3,3->4,3->5,3->6,3->6,4->6,5
  3. 3:1,1->2,1->3,1->3,2->3,3->4,3->4,2->5,2->5,3->5,4->6,4->6,5
  4. 4:1,1->2,1->3,1->3,2->3,3->4,3->4,2->5,2->5,3->6,3->6,4->6,5
  5. 5:1,1->2,1->3,1->3,2->4,2->4,3->5,3->5,4->6,4->6,5
  6. 6:1,1->2,1->3,1->3,2->4,2->4,3->5,3->6,3->6,4->6,5
  7. 7:1,1->2,1->3,1->3,2->4,2->5,2->5,3->5,4->6,4->6,5
  8. 8:1,1->2,1->3,1->3,2->4,2->5,2->5,3->6,3->6,4->6,5
复制代码
来源
回溯 深搜 递归
标签
回溯   深搜   递归

题解


标题大意

一只叫 Mitch 的老鼠在森林里嬉戏时误入了一个迷宫,这个迷宫出现为一个 n 行 m 列的矩阵形式。迷宫中的格子分为两种环境,能用小写字母 o 表现的格子是可以行走通过的,而用 # 表现的格子是不能走的 “停滞” 格子。Mitch 选择的走出迷宫计谋是有特定序次的,它会先实验向右走,如果右边走不通就向下走,向下走不通就向左走,向左走不通就向上走,要是四个方向都走不通,那就后退去选择其他能走的路径。Mitch 从迷宫的左上角(入口,且入口点不是 # )进入迷宫,需要编程求出它按照这个计谋能走出迷宫到达右下角点 (n, m) 的所有大概路径,并按照规定格式输出这些路径,如果不存在任何可行的走出迷宫的路径,那就输出 no 。
代码思路

  1. int n,mn,t=0,a[160][2];
  2. char m[19][19];
  3. int dx[]={0,1,0,-1};
  4. int dy[]={1,0,-1,0};
复制代码
  1. void p(int c){
  2.     // 输出路径序号
  3.     printf("%d:",t);
  4.     for(int i=1;i<=c;i++){
  5.         // 输出路径上每个点的坐标格式
  6.         printf("%d,%d->",a[i][0],a[i][1]);
  7.     }
  8.     // 输出终点坐标
  9.     printf("%d,%d\n",n,mn);
  10. }
复制代码

  1. if(x==n&&y==mn){
  2.     t++;//到达终点,增加一个路径
  3.     p(c-1);
  4.     return;
  5. }
复制代码


  1. m[x][y]='#';//到达某点,标记
  2. a[c][0]=x;
  3. a[c][1]=y;
复制代码


  1. int h,l;
  2. for(int i=0;i<4;i++){
  3.     h=x+dx[i];
  4.     l=y+dy[i];
  5.     if(h>0&&h<=n&&l>0&&l<=mn&&m[h][l]=='o'){
  6.         dfs(h,l,c+1);
  7.     }
  8. }
复制代码


  1. m[x][y]='o';//回溯
复制代码


  1. int main(){
  2.     cin>>n>>mn;
  3.     for(int i=1;i<=n;i++){
  4.         for(int j=1;j<=mn;j++){
  5.             cin>>m[i][j];
  6.         }
  7.     }
  8.     dfs(1,1,1);
  9.     if(t==0)
  10.         cout<<"no";
  11.     return 0;
  12. }
复制代码
完整代码

  1. #include<iostream>
  2. #include<cstring>
  3. using namespace std;
  4. // 定义迷宫的行数、列数,路径数量,记录路径坐标的数组以及存储迷宫布局的数组
  5. int n, mn, t = 0, a[160][2];
  6. char m[19][19];
  7. // 定义四个方向在横坐标上的偏移量,顺序为右、下、左、上
  8. int dx[] = { 0, 1, 0, -1 };
  9. // 定义四个方向在纵坐标上的偏移量,顺序为右、下、左、上
  10. int dy[] = { 1, 0, -1, 0 };
  11. // 函数功能:按照格式输出一条找到的可行路径
  12. // 参数 c 表示当前已经记录在数组 a 中的路径坐标个数(不包含终点坐标)
  13. void p(int c) {
  14.     // 输出路径序号
  15.     printf("%d:", t);
  16.     for (int i = 1; i <= c; i++) {
  17.         // 输出路径上每个点的坐标格式,用 -> 连接
  18.         printf("%d,%d->", a[i][0], a[i][1]);
  19.     }
  20.     // 输出终点坐标
  21.     printf("%d,%d\n", n, mn);
  22. }
  23. // 深度优先搜索函数,用于探索迷宫路径
  24. // 参数 x、y 表示当前所在位置的坐标,c 表示已经记录的路径坐标个数(包含当前位置坐标)
  25. void dfs(int x, int y, int c) {
  26.     // 判断是否到达终点(右下角坐标 (n, mn))
  27.     if (x == n && y == mn) {
  28.         t++;  // 到达终点,路径数量加 1
  29.         p(c - 1);  // 输出这条找到的路径,传入的参数是已经记录的有效坐标个数(不包含终点这次记录)
  30.         return;
  31.     }
  32.     // 将当前位置标记为已走过(用 # 标记,避免重复走)
  33.     m[x][y] = '#';
  34.     // 记录当前位置坐标到数组 a 中,方便后续输出路径
  35.     a[c][0] = x;
  36.     a[c][1] = y;
  37.     int h, l;
  38.     // 循环尝试四个方向(右、下、左、上)
  39.     for (int i = 0; i < 4; i++) {
  40.         h = x + dx[i];
  41.         l = y + dy[i];
  42.         // 判断新坐标是否在迷宫范围内且对应格子可走(是 'o')
  43.         if (h > 0 && h <= n && l > 0 && l <= mn && m[h][l] == 'o') {
  44.             // 满足条件则以新坐标为起点继续深度优先搜索,路径记录长度加 1
  45.             dfs(h, l, c + 1);
  46.         }
  47.     }
  48.     // 回溯操作,将当前位置标记还原为可走状态('o'),方便其他路径探索时可以再次访问
  49.     m[x][y] = 'o';
  50. }
  51. int main() {
  52.     cin >> n >> mn;
  53.     // 读取迷宫的每一行每一列的布局情况(字符 'o' 或者 '#')
  54.     for (int i = 1; i <= n; i++) {
  55.         for (int j = 1; i <= mn; j++) {
  56.             cin >> m[i][j];
  57.         }
  58.     }
  59.     // 从左上角坐标 (1, 1) 开始深度优先搜索路径,初始路径记录长度设为 1
  60.     dfs(1, 1, 1);
  61.     // 如果没有找到任何可行路径(路径数量 t 还是 0),输出 no
  62.     if (t == 0)
  63.         cout << "no";
  64.     return 0;
  65. }
复制代码
本题考察的知识点




免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4