小青蛙有一天不小心落入了一个地下迷宫,小青蛙希望用自己仅剩的体力值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;
}