hdu 1010

http://acm.hdu.edu.cn/showproblem.php?pid=1010

这个学习回溯法实践,深搜入门题,几个剪枝点

1. 奇偶剪枝,这在搜索进行前判断即可

2. 深度剪枝,最大深度T

3. 根据所剩时间和距离进行剪枝

4. 还可以根据所有可走的点与时间的差进行剪枝

5. 提前到达剪枝

分别写了递归和非递归算法,比较起来发现还是递归的快,通过调试发现搜索路径确实是一样的,不知道什么原因,还望知道的告诉声

递归法

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char maze[8][8];
int n,m,t,dx,dy;

int dfs(int x,int y,int left)
{
        int ret;
        if(left==0)
        {
                if(maze[x][y]=='D')
                        return 1;
                return 0;
        }
        if(x<0||y<0||x==n||y==m||maze[x][y]=='X'||maze[x][y]=='D')
                return 0;
        if(left-(abs(dx-x)+abs(dy-y))<0)
                return 0;
        if(left%2-(abs(dx-x)+abs(dy-y))%2)
                return 0;

        maze[x][y]='X';
        ret=dfs(x+1,y,left-1);
        if(ret)
                return ret;
        ret=dfs(x-1,y,left-1);
        if(ret)
                return ret;
        ret=dfs(x,y+1,left-1);
        if(ret)
                return ret;
        ret=dfs(x,y-1,left-1);
        if(ret)
                return ret;
        maze[x][y]='.';
        return 0;
}

int main()
{
        while(~scanf("%d%d%d",&n,&m,&t)&&n&&m&&t)
        {
                int i,j,x,y;
                for(i=0;i<n;i++)
                {
                        char *c;
                        scanf("%s",maze[i]);
                        c=strchr(maze[i],'S');
                        if(c!=NULL)
                        {
                                x=i;
                                y=c-maze[i];
                        }
                        c=strchr(maze[i],'D');
                        if(c!=NULL)
                        {
                                dx=i;
                                dy=c-maze[i];
                        }
                }
                if( dfs(x,y,t) )
                        printf("YES\n");
                else
                        printf("NO\n");
        }
        return 0;
}



迭代法

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int n,m,t;
char sx,sy,dx,dy;
char maze[10][10];
char dir[4][2]={{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
struct {
    char x;
    char y;
    char dir;
} road[50];

int dfs(int step)
{
    char x,y;
    while(step>=0)
    {
        while(road[step].dir<3)
        {
            road[step].dir++;
            x=road[step].x+dir[road[step].dir][0];
            y=road[step].y+dir[road[step].dir][1];
            if(x<0||y<0||x==n||y==m||maze[x][y]=='X')
                continue;
            else if(step+1==t&&maze[x][y]=='D')
                return 1;
            else if((t-step-1)<(abs(x-dx)+abs(y-dy)))
                continue;
            else if(maze[x][y]=='.')
            {
                step++;
                road[step].x=x;
                road[step].y=y;
                road[step].dir=-1;
                maze[road[step].x][road[step].y]='X';
            }
        }
        road[step].dir=-1;
        maze[road[step].x][road[step].y]='.';
        step--;
    }
    return 0;
}

int main()
{
    while(~scanf("%d%d%d",&n,&m,&t)&&n&&m&&t)
    {
        int i,j,tmp;
        memset(maze,0,sizeof(maze));
        for(i=0;i<n;i++)
        {
            char *c;
            scanf("%s",maze[i]);
            c=strchr(maze[i],'S');
            if(c!=NULL)
            {
                sx=i;
                sy=c-maze[i];
            }
            c=strchr(maze[i],'D');
            if(c!=NULL)
            {
                dx=i;
                dy=c-maze[i];
            }
        }

        tmp=t-(abs(sx-dx)+abs(sy-dy));
        if(tmp<0||tmp&1)
        {
            printf("NO\n");
            continue;
        }

        road[0].x=sx;
        road[0].y=sy;
        road[0].dir=-1;
        maze[sx][sy]='X';
        if(dfs(0))
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值