第一道深搜------------hdu1010
这几天一直在研究深搜,各种走迷宫。但归类一下,我用的解决方法就两种:1,非递归,用栈 2,递归
第一次按照数据额结构上的算法,用栈写了一个160行的走迷宫。复杂!写完之后,自己再想改就看不懂了!无语...........
我知道递归和回溯简单,但自己一直纠结于函数的返回值问题,心里没搞明白,不敢用。后来在《算法设计上》看到一句话‘在用递归算法实现时,将节点作为参数,这样参数栈就能存储现有的节点’,顿时泪流满面啊!!
我一直忘了,在函数递归时会自动建立一个参数栈。每次调用函数时,都会将参数入栈,回溯时参数自动出栈。我不用再杞人忧天,费劲儿的自己建栈了!
唉,可以归结为基础不牢固,...............任重道远啊!
不说了,看了杭电课件的算法,AC代码如下:
#include<iostream.h>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
char map[9][9];
int n,m,t,di,dj;
bool escape;
int dir[4][2]={{0,-1},{0,1},{1,0},{-1,0}};
void dfs(int si,int sj,int cnt)
{
int i,temp;
if(si>n||sj>m||si<=0||sj<=0)
return ;
if(cnt==t&&si==di&&sj==dj)
escape=1;
if(escape) return ;
temp=(t-cnt)-abs(si-di)-abs(sj-dj); //这两行很恶,奇偶剪枝,少了这两行会超时1000ms。剪枝后62ms。
if(temp<0||temp&1) return ; //很神奇啊!但 temp&1 这点我还没看懂,改成temp==1就不行。以后好好看看!
for(i=0;i<4;i++)
{
if(map[si+dir[i][0]][sj+dir[i][1]]!='X')
{
map[si+dir[i][0]][sj+dir[i][1]]='X';
dfs(si+dir[i][0],sj+dir[i][1],cnt+1);
map[si+dir[i][0]][sj+dir[i][1]]='.';
}
}
return ;
}
int main()
{
int i,j,si,sj;
while(cin>>n>>m>>t)
{
if(n==0&&m==0&&t==0)
break;
int wall=0;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
cin>>map[i][j];
if(map[i][j]=='S')
{
si=i;
sj=j;
}
else if(map[i][j]=='D')
{
di=i;
dj=j;
}
else if(map[i][j]=='X')
wall++;
}
}
if(n*m-wall<=t)
{
cout<<"NO"<<endl;
continue;
}
escape=0;
map[si][sj]='X';
dfs(si,sj,0);
if(escape)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}