题目:https://www.nowcoder.com/questionTerminal/ddebdb03fec547c3bb2adbb20bd29913
Input:
4 4 5
S.X.
..X.
..XD
….
3 4 5
S.X.
..X.
…D
0 0 0
Output:
NO
YES
思路简单:就是以S为起点的深度搜索(因为是存在问题我们用深度搜索),若在规定时间点抵达D则停止递归,当然超时我们也停止当前递归。
下面说说递归为什么容易超时:
- 调用函数耗时,而递归就是一个不断自己调用自己的过程。所以最好遇到终点时先考虑终点合不合格,然后再决定是否继续搜索。
- 最关键的一点,再进行进一步的递归完成以后,要直接判断是不是已经可以停止搜索了。
- 合理剪枝。
#include<stdio.h>
#define SZ 7
using namespace std;
int N,M,T;
char ch[SZ][SZ];
bool mark[SZ][SZ];
int flag;
int mp[][2]= {0,1,
0,-1,
1,0,
-1,0
};
void Try(int x,int y,int t) {
// printf("%d %d %d\n",x,y,t);
if(ch[x][y]=='D') {
if(t==T)
flag=true;
return;
}
if(t>=T) return;
int nx,ny;
for(int i=0; i<4; i++) {
nx=x+mp[i][0];
ny=y+mp[i][1];
if(nx>N||nx<1||ny>M||ny<1) continue;
if(ch[nx][ny]=='X') continue;
if(mark[nx][ny]) continue;
mark[nx][ny]=true;
Try(nx,ny,t+1);
mark[nx][ny]=false;
if(flag) return;//这一句必须要加!!否则会超时。
}
}
int main() {
while(scanf("%d %d %d",&N,&M,&T)!=EOF) {
flag=false;
int sx,sy,dx,dy;
getchar();
if(N==0&&M==0&&T==0) break;
for(int i=1; i<=N; i++) {
for(int j=1; j<=M; j++) {
mark[i][j]=false;
scanf("%c",&ch[i][j]);
if(ch[i][j]=='S') {
sx=i;
sy=j;
}
if(ch[i][j]=='D'){
dx=i;
dy=j;
}
}
getchar();
}
if((dx+dy)%2==0){
if((sx+sy)%2==0&&T%2!=0){
cout<<"NO"<<endl; continue;
}
if((sx+sy)%2!=0&&T%2==0){
cout<<"NO"<<endl; continue;
}
}
if((dx+dy)%2!=0){
if((sx+sy)%2!=0&&T%2!=0){
cout<<"NO"<<endl; continue;
}
if((sx+sy)%2==0&&T%2==0){
cout<<"NO"<<endl; continue;
}
}
mark[sx][sy]=true;
Try(sx,sy,0);
if(flag) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}