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

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值