hdu 1010Tempter of the Bone(dfs+剪枝)

来源:互联网 发布:北京百知尚行是培训吗 编辑:程序博客网 时间:2024/05/24 07:15

题意:有一个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;}


0 0
原创粉丝点击