思路
我相信能查到这儿的伙伴一定已经看过了题目了,那就开门见山,谈谈这题的思路。在考场上,我第一想法是用DFS,尝试了一下,没有跑出来,以为DFS用的隐式的栈,所以无法直接跑出答案。回来后,我用BFS尝试了一下,成功解出了答案。代码和注释如下。
#include<queue>
#include<windows.h>
#include<iostream>
using namespace std;
typedef pair<int,int> p;
const int INF=100000000;
#define row 30
#define cow 50
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
char graph[35][55];
int tar[35][55];
pair<int,int> qian[35][55];
void bfs()
{
queue<p> s;
int i,j;
for(i=0;i<row;i++) //初始距离设一下这样就没必要记录是否访问过,一举两得
for (j=0;j<cow;j++)
tar[i][j]=INF;
s.push(pair<int,int>(0,0)); //头结点入栈
tar[0][0]=0;
while(s.size())
{
p q=s.front();
s.pop();
if (q.first==row-1 && q.second==cow-1) //找到目标结束
return;
for (i=0;i<4;i++)
{
int nx=q.first+dx[i];
int ny=q.second+dy[i];
if (0<=nx && nx<row && ny>=0 && ny<cow && graph[nx][ny]!='1' && tar[nx][ny]==INF) //1.不能越界 2.该点可访问 3.该点未访问过
{
s.push(pair<int ,int>(nx,ny)); //搜到该点,就入栈
qian[nx][ny]=pair<int,int>(q.first,q.second); //记录前一个结点,便于回溯
tar[nx][ny]=tar[q.first][q.second]+1; //路径加一
}
}
}
}
void show(int cur_x,int cur_y,int qi_x,int qi_y)
{
if (cur_x==qi_x+1 && cur_y==qi_y) //右
{
cout<<"R";
}
else if (cur_x==qi_x-1 && cur_y==qi_y) //左
{
cout<<"L";
}
else if (cur_x==qi_x && cur_y==qi_y+1) //下
{
cout<<"D";
}
else if (cur_x==qi_x && cur_y==qi_y-1) //上
{
cout<<"U";
}
}
int main ()
{
int i,j;
for (i=0;i<row;i++)
for (j=0;j<cow;j++)
cin>>graph[i][j];
bfs();
int qi_x,qi_y,temp;
qi_x=row-1;qi_y=cow-1;
while(qi_x!=0 || qi_y!=0) //回溯法
{
show(qi_x,qi_y,qian[qi_x][qi_y].first,qian[qi_x][qi_y].second); //倒序找该点
temp=qi_x; //此处注意因为q_x将被改变,所以必须先存一个值
qi_x=qian[qi_x][qi_y].first;
qi_y=qian[temp][qi_y].second;
}
cout<<tar[row-1][cow-1]<<endl;
return 0;
}
优化
在网上看到诸位大牛在使用BFS或DFS搜索时都会用到剪枝的方法提高算法的效率,等我日后有空再补上优化过程。