题意:有一个N*M的迷宫,‘.’代表能走的格子,‘X’代表墙,‘S’代表入口,‘D’代表出口,如果能在规定时间内到达出口,输出“YES”,否则输出“NO”。
分析:感觉自己老是不会搜索,看了几段课程后想开始练练搜索【不知道为什么一直不喜欢搜索题,所以一直没做这个专题】,感觉这题很经典。
#include <iostream>
#include<cmath>
using namespace std;
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 (si==di && sj==dj && cnt==t)
{escape=1;return;}
temp=abs(t-cnt)-(abs(di-si)+abs(dj-sj));
if (temp<0 || temp&1) return; //奇偶剪枝:因为目标步数和最短距离的差只能是偶数!
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'; //如果可以走的话就走这个位置的就定位为'X'
DFS(si+dir[i][0],sj+dir[i][1],cnt+1); //加上走的步数继续搜索
if (escape)return; //如果搜索不成功就判断一下是不是到了终点
map[si+dir[i][0]][sj+dir[i][1]]='.'; //没有到达终点返回就把原来的位置置为未走过
}
}
return ;
}
int main()
{
int i,j,si,sj,wall;
while (cin>>n>>m>>t)
{
if (n==0 && m==0 && t==0)break;
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) //这步也有点取巧的意味,如果能走的步数少于规定的步数,就直接输出no
{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;
}