1>问题描述
2>自己最初的版本(读者可跳过)
/*
* 这种要便利每种结果(具体路径)的一般用dfs;如果只求最大/最小结果的种类数,优先考虑动态规划
* 自己写的最初版本存在两个主要问题:
* 1.最关键的问题,已经走过的位置没有进行标记,导致可能重复走,所以超时了
* 2.要求输出有效路径中消费能量最少的路径,没有效路径时打印错误消息
* 应该有全局变量保存已找到的有效路径的消费能量值,当有新的有效路径时,进行比较判断是否更新路径
* 所以函数process不用返回,void 就OK了;没必要根据返回值判断是否存在有效路径,根据result是否为空就能判断
*/
#include<iostream>
#include<vector>
using namespace std;
class point
{
public:
int row;
int col;
point():row(0),col(0){}
point(int i,int j):row(i),col(j){}
};
//问题1
bool process(vector<vector<int>>&grid,int i,int j,vector<point> &res,int P)
{
int rows = grid.size();
int cols = grid[0].size();
if(i==0&&j==cols-1 && P>=0)
return true;
if(P<0 && !(i==0&&j==cols-1))
return false;
//往下走
if(i<rows-1 &&grid[i+1][j]==1)
{
res.push_back(point(i+1,j));
if(process(grid,i+1,j,res,P))
return true;
res.pop_back();
}
//往左走
if(j>0 && grid[i][j-1]==1)
{
res.push_back(point(i,j-1));
if(process(grid,i,j-1,res,P-1))
return true;
res.pop_back();
}
//往右走
if(j<cols-1 &&grid[i][j+1]==1)
{
res.push_back(point(i,j+1));
if(process(grid,i,j+1,res,P-1))
return true;
res.pop_back();
}
//往上走
if(i>0 &&grid[i-1][j]==1)
{
res.push_back(point(i-1,j));
if(process(grid,i-1,j,res,P-3))
return true;
res.pop_back();
}
return false;
}
int main()
{
int n=0,m=0,P=0;
vector<vector<int>>grid;
while(cin>>n>>m>>P)
{
grid.resize(n);
for(int i=0;i<n;++i)
grid[i].resize(m,0);
for(int i=0;i<n;++i)
for(int j=0;j<m;++j)
cin>>grid[i][j];
vector<point> res;
int Yes = 0;
res.push_back(point(0,0));
if(process(grid,0,0,res,P)==false)
cout<<"Can not escape!"<<endl;
else
{
int len = res.size();
for(int i=0;i<len;++i)
{
if(i<len-1)
cout<<"["<<res[i].row<<","<<res[i].col<<"]"<<",";
else
cout<<"["<<res[i].row<<","<<res[i].col<<"]"<<endl;
}
}
}
}
运行结果:
2>根据上面的问题就行改动
#include<iostream>
#include<vector>
using namespace std;
class point
{
public:
int row;
int col;
point():row(0),col(0){}
point(int i,int j):row(i),col(j){}
};
vector<point> result;
//maxP用于保存有效路径走出出口时还剩的能量值
//根据它可以判断是否更新要输出的有效路径
//这里如果初始化为0,下面的标记1就应该改为 P>=maxP
//因为如果只有一条有效路径,并且剩余能量为0,那么应该执行result = res;
int maxP=-1;
void process(vector<vector<int>>&grid,int i,int j,vector<point> &res,int P)
{
/*(i,j)这个位置是已经走了的,下面是判断下一步走到哪个位置*/
int rows = grid.size();
int cols = grid[0].size();
if(P<0 && !(i==0&&j==cols-1))
return;
//此路可行
if(i==0&&j==cols-1&&P>=0)
{
//说明该有效路径剩余的能量值比之前的有效路径剩余的多
//更新结果result与maxP
if(P>maxP)//标记1
{
maxP = P;
result = res;
}
return;
}
//往左走
if(j-1>=0 && grid[i][j-1]==1)
{
//标记该位置,防止走回头路,这是提高效率的关键
grid[i][j-1] = 0;
res.push_back(point(i,j-1));//线添加到路线
process(grid,i,j-1,res,P-1);
grid[i][j-1] = 1;//恢复该位置的可走性
res.pop_back();//从路线中弹出
}
//往右走
if(j+1<cols &&grid[i][j+1]==1)
{
grid[i][j+1] = 0;
res.push_back(point(i,j+1));
process(grid,i,j+1,res,P-1);
grid[i][j+1] = 1;
res.pop_back();
}
//往上走
if(i-1>=0 &&grid[i-1][j]==1)
{
grid[i-1][j] = 0;
res.push_back(point(i-1,j));
process(grid,i-1,j,res,P-3);
grid[i-1][j] = 1;
res.pop_back();
}
//往下走
if(i+1<rows &&grid[i+1][j]==1)
{
grid[i+1][j]=0;
res.push_back(point(i+1,j));
process(grid,i+1,j,res,P);
grid[i+1][j]=1;
res.pop_back();
}
}
int main()
{
int n=0,m=0,P=0;
vector<vector<int>>grid;
while(cin>>n>>m>>P)
{
grid.resize(n);
for(int i=0;i<n;++i)
grid[i].resize(m,0);
for(int i=0;i<n;++i)
for(int j=0;j<m;++j)
cin>>grid[i][j];
vector<point> res;
res.push_back(point(0,0));//先添加起点
process(grid,0,0,res,P);
if(!result.size())//根据result是否为空,判断有效路径是否存在
cout<<"Can not escape!"<<endl;
else
{
int len = result.size();
for(int i=0;i<len;++i)
{
if(i<len-1)
cout<<"["<<result[i].row<<","<<result[i].col<<"]"<<",";
else
cout<<"["<<result[i].row<<","<<result[i].col<<"]"<<endl;
}
}
}
}
运行结果: