HDU1728 逃离迷宫 DFS练习题

这道题其实单纯使用DFS实现并不难,在函数里面加一个转弯次数的形参就行。刚拿到这道题我确实也是这么做的。

但是把代码提交之后出现了DFS很常见的问题——超时,后来在讨论区发现大部门AC的代码都是使用的BFS+优先队列,因为DFS都写出来了就不想改了,再说也有用DFS成功AC的呀。看了大牛的代码知道加一个数组进行剪剪枝就行。

#include <iostream>
#include <cstdio>
#include <string.h>

using namespace std;

int to[4][2]={1,0,-1,0,0,1,0,-1};
char map[105][105];
int turn[105][105];
int sx,sy,ex,ey,swerve,nowtime;
bool endn=false;
int m,n;

void dfs(int x,int y,int flag){
    if(nowtime>swerve) return;
    if(x==ex&&y==ey){
        endn=true;
    }
    if(endn) return;
    //cout<<x<<" "<<y<<" "<<map[x][y]<<endl;
    map[x][y]='*';
    for(int i=0;i<4;i++){
        int xn=x+to[i][0],yn=y+to[i][1];
        if(map[xn][yn]!='.') continue;
        if(turn[xn][yn]<turn[x][y]) continue;               //剪枝!!!!如果到达点xn,yn时之前有到达过,并且转弯次数少于本次时,剪去
        if(i<2){
            if(flag==1||flag==0){
                turn[xn][yn]=turn[x][y];
                dfs(xn,yn,1);
            }else{
                nowtime++;
                turn[xn][yn]=turn[x][y]+1;  //剪枝数组值的改变
                dfs(xn,yn,1);
                nowtime--;
            }
        }else{
            if(flag==-1||flag==0){
                turn[xn][yn]=turn[x][y];
                dfs(xn,yn,-1);
            }else{
                nowtime++;
                turn[xn][yn]=turn[x][y]+1;
                dfs(xn,yn,-1);
                nowtime--;
            }
        }
    }
    map[x][y]='.';
}
int main()
{
    int t;
    cin>>t;
    while(t--){
        endn=false;
        memset(map,0,sizeof(map));
        memset(turn,999999,sizeof(turn));    //初始化剪枝数组要无限大,因为后面就是要筛选转弯次数少的路。
        nowtime=0;
        cin>>m>>n;
        for(int i=1;i<=m;i++)
            for(int j=1;j<=n;j++){
                cin>>map[i][j];
            }
        //cout<<map[2][1]<<endl;
        cin>>swerve>>sy>>sx>>ey>>ex;
        turn[sx][sy]=0;
        dfs(sx,sy,0);
        if(endn) cout<<"yes"<<endl;
        else{
            cout<<"no"<<endl;
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_38071217/article/details/76625277