这道题磨了我一个下午,虽然在大神帮助下完成,要注意的东西太多,之前还用了宽搜,那是每看懂题目意思,宽搜是找到一条最短路,而这道题不一定是最短路,要在规定的时间到达,换句话说就是有规定的步数,走了的不能再走。
写题中遇到以下几个问题:
1.对于深搜还是没有完全理解,由于是递归,所以每次的函数体应该都是一样的,之前把不该改变的起点步数清零放在递归函数里,导致错误。
2.对于我之前有点画蛇添足,我又加了个结构体,存迷宫每个点的横纵坐标和信息,然后我在递归结束条件那里直接判断的,但是我在赋值又没有对每个点赋值,导致出错,太粗心了。看下面的错误!!
typedef struct dd{
int a,b;
char sr;
}dd;
bool dfs(dd t,int dis){
if((t.sr==‘D‘)&&(dis==ti))
return true;
for(int i=0;i<4;i++){
s.a=t.a+x[i];
s.b=t.b+y[i];//少了一个s.sr=maze[s.a][s.b],太粗心拉
}
3.这题的特殊是在递归时返回上层应返回可不可行,而不仅仅是继续搜下去,所以有如下:
if(dfs(s,dis+1))
return true;
4.全部完成了以后还是超时,要剪枝!由曼哈顿距离,总的耗时=曼哈顿距离+多余的路,并且多余的路一定是个偶数,否则不能到达。曼哈顿距离=|起点横坐标-终点横坐标|+|起点纵坐标-终点纵坐标|。然后这题就好啦><
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<queue>
#include<math.h>
#include<algorithm>
using namespace std;
int x[4]={-1,0,0,1};
int y[4]={0,-1,1,0};
char maze[10][10];
int vis[10][10];
int ti,n,m;
typedef struct dd{
int a,b;
char sr;
}dd;
dd st,en;
bool dfs(dd t,int dis){
if((maze[t.a][t.b]==‘D‘)&&(dis==ti))//之前在这犯错误,改了一下
return true;
if(dis>ti)
return false;
dd s;
for(int i=0;i<4;i++){
s.a=t.a+x[i];
s.b=t.b+y[i];
if(s.a>=0&&s.a<n&&s.b>=0&&s.b<m&&maze[s.a][s.b]!=‘X‘&&!vis[s.a][s.b]){
vis[s.a][s.b]=1;
if(dfs(s,dis+1))
return true;
vis[s.a][s.b]=0;
}
}
return false;
}
int main(){
while(scanf("%d%d%d",&n,&m,&ti)!=EOF){
if(n==0&&m==0&&ti==0)
break;
getchar();
memset(vis,0,sizeof(vis));
for(int i=0;i<n;i++){
for(int j=0;j<m;j++)
scanf("%c",&maze[i][j]);
getchar();
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(maze[i][j]==‘S‘){
st.sr=maze[i][j];
st.a=i;
st.b=j;
}
else if(maze[i][j]==‘D‘){
en.a=i;
en.b=j;
}
}
}
vis[st.a][st.b]=1;
if(((ti-(st.a-en.a+st.b-en.b))%2==0)&&dfs(st,0))//剪枝,否则超时
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}
深搜--Tempter of the Bone hdu1010
原文:http://www.cnblogs.com/wsyxy/p/4279531.html