Loading

[HDU - 1010 ]Tempter of the Bone

这道也是典型的DFS迷宫。算是简单的了。

/*对于此题的理解
一开始认为与走砖块差不多但后来发现有很多地方我实现不了
学习了此题便可以解决一系列找宝藏问题
这题重要的地方就是
1.奇偶剪枝
2.找到目标退出(最优路径便无需推出)
3.方向循环里该如何编写的学习
4.墙数与地图可行数对题目的优化*/


#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;

char map[10][10];
int visit[10][10];
int n,m,t,ex,ey,flag;

void dfs(int sx,int sy,int step)
{
    int i,dx,dy;
    int next[4][2]={{-1,0},{1,0},{0,1},{0,-1}};//方向数组
    if(flag)//很重要,可以减少步骤,也是如何使一旦找到需要的路线就可以连续return出
        return;
    if(sx==ex&&sy==ey&&step==t)
    {
        flag=1;
        return;
    }
    int tem=t-step-abs(ex-sx)-abs(ey-sy);//剪枝的核心代码
    if(tem<0||tem&1)//剪枝:如果剩余的步数已经不足以走到出口,且必须是偶数,偶数-偶数=偶数,奇数-奇数=偶数,
        return;
    for(i=0;i<4;i++)
    {
        dx=sx+next[i][0];
        dy=sy+next[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);
            if(flag)//若找到结果,及时return
                return;
            visit[dx][dy]=0;//注意返回标记 以便下次搜索
        }
    }
    return ;
}

int main()
{
    int i,j,wall;
    int sx,sy;
    while(~scanf("%d %d %d",&n,&m,&t))
    {
        if(n==0&&m==0&&t==0)
            break;
        flag=0;wall=0;
        memset(visit,0,sizeof(visit));
        for(i=0;i<n;i++)
        {
            scanf("%s",map[i]);
        }
        for(i=0;i<n;i++)
        {
            for(j=0;j<m;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++;
            }
        }
        if(t>n*m-wall-1)//注意时间与墙数和地图的数量关系会减少很多步骤哦
        {
            printf("NO\n");
            continue;
        }
        visit[sx][sy]=1;//务必记得标记走过的路径
        dfs(sx,sy,0);
        if(flag==1)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}
View Code

 

posted @ 2019-08-20 13:50  ViKyanite  阅读(123)  评论(0编辑  收藏  举报