小青蛙走迷宫的问题

12 篇文章 0 订阅
9 篇文章 0 订阅

小青蛙有一天不小心落入了一个地下迷宫,小青蛙希望用自己仅剩的体力值P跳出这个地下迷宫。为了让问题简单,假设这是一个n*m的格子迷宫,迷宫每个位置为0或者1,0代表这个位置有障碍物,小青蛙达到不了这个位置;1代表小青蛙可以达到的位置。小青蛙初始在(0,0)位置,地下迷宫的出口在(0,m-1)(保证这两个位置都是1,并且保证一定有起点到终点可达的路径),小青蛙在迷宫中水平移动一个单位距离需要消耗1点体力值,向上爬一个单位距离需要消耗3个单位的体力值,向下移动不消耗体力值,当小青蛙的体力值等于0的时候还没有到达出口,小青蛙将无法逃离迷宫。现在需要你帮助小青蛙计算出能否用仅剩的体力值跳出迷宫(即达到(0,m-1)位置)。
输入描述:

输入包括n+1行:

第一行为三个整数n,m(3 <= m,n <= 10),P(1 <= P <= 100)

接下来的n行:

每行m个0或者1,以空格分隔

输出描述:

如果能逃离迷宫,则输出一行体力消耗最小的路径,输出格式见样例所示;如果不能逃离迷宫,则输出”Can not escape!”。
测试数据保证答案唯一

输入例子:
4 4 10
1 0 0 1
1 1 0 1
0 1 1 1
0 0 1 1
输出例子:
[0,0],[1,0],[1,1],[2,1],[2,2],[2,3],[1,3],[0,3]

分析:该问题属于迷宫求最短路径的问题!那么怎么求迷宫最短路径呢?

迷宫路径 、最短路径的问题:
迷宫路径:使用探测发,用一个栈保存路径;并且将上一个走过的路径标记。然后分别取探测改点的上、下、左、右是否可通,如果可通:递归进入该点,并把改点入栈;
递归的终止条件是到了出口(一般迷宫会规定出口);

最短路径的问题: 在上个问题的基础上我们定义个全局的数组 res;用来保存短路径。之后如果再次找到一条迷宫路径就和 res比较,如果他的size小于res,就把这条路径赋值给res

上代码:

#include<stdio.h>
#include<vector>

#include<iostream>
using namespace std;
//将位置封装成一个结构体,路径res存放的就是结构体
struct Node
{
  int x;
  int y;
};

int n,m,p,step = 999999;
vector<Node> res;//保存最优路径
int a[10][10];//定义了10*10大小的迷宫
bool is_visit[10][10] = { false };//标记走过的位置(true:已经走过;false:还没走过)

void findpath(vector<Node>& tmp, int energy, int i, int j)//运用了递归+上下探测的方法;
//如果当前位置的上、下、左、右可通,将其入栈,并且递归进去,并将当前位置标记;
//如果这条路不是最优路径或者不通,递归就会返回,再将该位置出栈,并把该位置的标记取消
{
  if(i == 0 && j == m-1)//走到了出口处
  {
    if(energy < p && energy < step)//判断改路径是否比上条路径更好(即比较消耗的能量)
    {
      step = energy;
      res = tmp;
    }
    return;
  }
  //上 
  if(i-1 >= 0 && a[i-1][j]== 1 && is_visit[i-1][j]==false)//如果这个位置合法,可通并且没有走过;则进入该位置
  {
    energy += 3;
    Node node;
    node.x = i-1;
    node.y = j;
    tmp.push_back(node);//将该位置入栈
    is_visit[i-1][j] = true;//标记为走过
    findpath(tmp, energy, i-1, j);
    energy -= 3;
    tmp.pop_back();//出栈
    is_visit[i-1][j] =false;//取消标记
  }
  //右
  if(j+1 < m && a[i][j+1] == 1 && is_visit[i][j+1] == false)
  {
    energy += 1;
    Node node;
    node.x = i;
    node.y = j+1;
    tmp.push_back(node);
    is_visit[i][j+1] = true;
    findpath(tmp, energy, i, j+1);
    energy -= 1;
    tmp.pop_back();
    is_visit[i][j+1] =false;
  }
  //下
  if(i+1 < n && a[i+1][j] == 1 && is_visit[i+1][j] == false)
  {
    energy += 0;
    Node node;
    node.x = i+1;
    node.y = j;
    tmp.push_back(node);
    is_visit[i+1][j] = true;
    findpath(tmp, energy, i+1, j);
    energy -= 0;
    tmp.pop_back();
    is_visit[i+1][j] = false;
  }
  //左
  if(j-1 >= 0 && a[i][j-1] == 1 && is_visit[i][j-1] == false)
  {
    energy += 1;
    Node node;
    node.x = i;
    node.y = j-1;
    tmp.push_back(node);
    is_visit[i][j-1] = true;
    findpath(tmp, energy, i, j-1);
    energy -= 1;
    tmp.pop_back();
    is_visit[i][j-1] = false;
  }
}

int main()
{
  cin>>n>>m>>p;
  for(int i = 0; i < n; ++i)
  {
    for(int j = 0; j < m; ++j)
      cin>>a[i][j];
  }

  vector<Node> tmp;
  int energy = 0;
  Node node;
  node.x = 0;
  node.y = 0;
  tmp.push_back(node);//将起点保存
  is_visit[0][0] = true;

  findpath(tmp, energy, 0, 0);

  if(step == 999999)
    cout<<"没有出路!";
  else 
  {
    int i = 0;
    for(i = 0; i < res.size()-1; ++i)
    {
      cout<<"["<<res[i].x<<","<<res[i].y<<"]"<<",";
    }
    cout<<"["<<res[i].x<<","<<res[i].y<<"]";
    cout<<endl;
  }

  return 0;
}

青蛙GD32F303库函数是一组用于开发基于GD32F303芯片的小青蛙项目的函数集合。它提供了丰富的功能和接口,使得开发者可以轻松地控制和操作芯片的各种功能。 在小青蛙GD32F303库函数中,包含了众多的功能模块,如时钟控制、GPIO控制、中断控制、定时器、ADC、UART和SPI等。通过这些库函数,开发者可以方便地配置和使用这些功能模块,实现小青蛙项目的各种需求。 比如,开发者可以使用库函数来配置和控制GPIO口的输入输出状态,实现与其他外设的连接和通信。通过配置时钟控制模块,开发者可以设置系统时钟频率,以满足不同的应用需求。 而定时器和中断控制模块的库函数,可以帮助开发者实现定时任务和中断处理的功能。通过配置定时器的计数值和中断触发条件,开发者可以实现定时触发某些操作或处理特定的中断事件。 另外,库函数还提供了ADC模块的配置和使用函数,以便开发者能够实现模拟信号的采集和转换。UART和SPI模块的库函数则可以帮助开发者实现与其他设备之间的串通信和数据交换。 总的来说,小青蛙GD32F303库函数提供了一套简洁、高效的代码接口,使得开发者能够更加方便地进青蛙项目的开发和调试工作。无论是控制IO口、配置时钟、处理定时器中断,还是进模拟信号采集和串通信,开发者都可以使用库函数来简化开发流程,提高开发效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值