您的位置:首页 > 其它

hdu 1728 逃离迷宫 剪枝DFS

2017-10-31 19:48 465 查看
有两点需要注意。

第一点是转弯问题,准备一个数组来存放到达每个点最小的转弯数。

第二点就是剪枝了

剪枝1:如果求出来了,直接return

剪枝2:如果当前已经大于最大转弯数了,直接return

剪枝3:第二次到达某个点时,如果转弯数大于之前到达的一次,直接return

剪枝4:同样第二次到达某点,如果方向不一样我们还要+1,判断+1之后是否大于之前到达的那一次,如果大于了直接return

#include <stdio.h>  

#include <string.h>  

#include <math.h>  

#define Max 999999  

#include <algorithm>  

using namespace std;  

  

struct point   

{  

    int x,y;  

}s[20000];  

  

char map[110][110];  

int turn[110][110];  

int n,m,x2,y2,ok,k;  

int dx[4]={1,-1,0,0};  

int dy[4]={0,0,1,-1};  

  

void dfs(int x,int y,int dir)  

{  

    int i,xx,yy;  

    if(x==x2 && y==y2 && turn[x][y]<=k)     

    {  

        ok=1;  

        return ;  

    }  

    if(turn[x][y]>k)          //剪枝1:如果超出步数,return

        return ;  

  

    if(x!=x2 && y!=y2 && turn[x][y]==k)    //剪枝2:如果没有步数了,还没到。return    

        return ;  

    for(i=0;i<4;i++)   

    {  

        xx=x+dx[i];  

        yy=y+dy[i];  

        if(xx<=0 || yy<=0 || xx>m || yy>n || map[xx][yy]=='*')  

                continue;  

        if(turn[xx][yy]<turn[x][y])    //剪枝3:如果已经去过了,转的比之前的多,直接return。     

            continue;  

        if(dir!=-1 && i!=dir && turn[xx][yy]<turn[x][y]+1)  //如果想过去我们还要转一次玩。同剪枝3再判断一次

            continue;            

        if(dir!=-1 && i!=dir)  

            turn[xx][yy]=turn[x][y]+1;  

        else  

            turn[xx][yy]=turn[x][y];  

        map[xx][yy]='*';      

        dfs(xx,yy,i);  

        map[xx][yy]='.';       

        if(ok)  

            return ;  

    }  

  

}  

  

  

  

int main()  

{  

    int i,j,t,x1,y1;  

    scanf("%d",&t);  

    while(t--)  

    {  

        scanf("%d%d",&m,&n);  

        for(i=1;i<=m;i++)  

            for(j=1;j<=n;j++)  

                scanf(" %c",&map[i][j]);  

        scanf("%d%d%d%d%d",&k,&y1,&x1,&y2,&x2);    

        memset(turn,Max,sizeof(turn));        

        ok=0;  

        turn[x1][y1]=0;  

        dfs(x1,y1,-1);  

        if(ok)  

            printf("yes\n");  

        else  

            printf("no\n");  

    }  

    return 0;  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: