天天写算法之Tempter of the Bone

地址: 点击打开链接
如我所想,跨过了BFS,就是DFS,然而上来的这个题和我想得不大一样,还难了一些。

用的是递归的方法。而且里面还有许多小trick

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define inf 0x3f3f3f3f
#define MAX 10
#define repf(i,from ,to) for(int i =from ; i <to ; i++)
using namespace std;

char Map[MAX][MAX];
int visit[MAX][MAX];
int d[4][2]={{-1,0},{1,0},{0,1},{0,-1}};
int n,m,t,ex,ey,flag;

//迭代深搜
void dfs(int sx,int sy,int step)
{
    int i,dx,dy;
    if(sx==ex&&sy==ey&&step==t)
    {
        flag =1 ;
        return ;
    }
    int item = t-step-abs(ex-sx)-abs(ey-sy);
    //进行剪枝操作
    if(item<0||item&1)
        return ;
    for(i = 0 ; i <4 ; i ++)
    {
        dx = sx+d[i][0];
        dy = sy+d[i][1];
        //越界的情况 ,直接跳
        if(dx<0||dy>=m||dy<0||dx>=n)
            continue ;
        if(Map[dx][dy]!='X'&&visit[dx][dy]==0)
        {
            visit[dx][dy]=1;
            dfs(dx,dy,step+1);
            visit[dx][dy]=0;
        }
    }
    return ;
}
int main(){
    int i , j , wall ;
    int sx,sy;
    while(cin>>n>>m>>t)
    {
        if(n==0&&m==0&&t==0)
            break;
        flag = 0 ;
        //对wall进行计数的目的是为了实现后面的一个小trick
        wall = 0 ;
        memset(visit,0,sizeof(visit));
        for(i = 0 ; i < n ; i++)
        {
            for(j = 0 ;j<m;j++)
            {
                cin>>Map[i][j];
                if(Map[i][j]=='S')
                {
                    sx=i;sy=j;
                }
                if(Map[i][j]=='D')
                {
                    ex = i,ey=j;
                }
                if(Map[i][j]=='X')
                {
                    wall++;
                }
            }
        }
        //trick one ,这个可以举个例来看一下,就知道对错了,因为t是必须准时进行。
        if(t+wall+1>m*n)
        {
            cout <<"NO"<<endl;
            continue ;
        }
        //出发点可以直接设置为已经搜索
        visit[sx][sy]=1;
        //迭代深搜
        dfs(sx,sy,0);
        if(flag==1)
        {
            cout << "YES"<<endl;
        }
        else {
            cout << "NO" <<endl;
        }

    }
    return 0 ;

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值