深度优先搜索 (DFS) hdu 1728

逃离迷宫

问题描述:

给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有些地方是障碍,她必须绕行,从迷宫的一个位置,只能走到与它相邻的4个位置中,当然在行走过程中,gloria不能走到迷宫外面去。令人头痛的是,gloria是个没什么方向感的人,因此,她在行走过程中,不能转太多弯了,否则她会晕倒的。我们假定给定的两个位置都是空地,初始时,gloria所面向的方向未定,她可以选择4个方向的任何一个出发,而不算成一次转弯。gloria能从一个位置走到另外一个位置吗?

输入:

  第1行为两个整数m, n (1 ≤ m, n ≤ 100),分别表示迷宫的行数和列数,接下来m行,每行包括n个字符,其中字符’.’表示该位置为空地,字符’*’表示该位置为障碍,输入数据中只有这两种字符,每组测试数据的最后一行为5个整数k, x1, y1, x2, y2 (1 ≤ k ≤ 10, 1 ≤ x1, x2 ≤ n, 1 ≤ y1, y2 ≤ m),其中k表示gloria最多能转的弯数,(x1, y1), (x2, y2)表示两个位置,其中x1,x2对应列,y1, y2对应行。

输出:

每组测试数据对应为一行,若gloria能从一个位置走到另外一个位置,输出“yes”,否则输出“no”。

Sample Input

5 5
…**
.*.
…..
…..
*….
1 1 1 1 3

Sample Output
no

Sample Input

5 5
…**
.*.
…..
…..
*….
2 1 1 1 3

Sample Output

yes

代码

#include "stdafx.h"

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

#define MAX 999999

char Map[100][100];
int turn[100][100];
int n, m;
int x2,y2,k; //终点坐标以及最多能turn的次数
int flag;//记录是否可以的标识

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) {//成功的条件
        flag = 1;  
        return ; 
    }
    if(turn[x][y] > k) {//不行的时候返回条件
        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] == '*') { //超出Map范围即是不能走
            continue;
        }

        if(turn[xx][yy] < turn[x][y]) {//turn[xx][yy] < turn[x][y]成立说明,xx,yy已经走过!这也是为啥main函数初始化turn为MAX  
            continue;  //思考为什么这里 = 不进行剪枝!
        }
        //如果从(x,y)走一步到(xx,yy)需要转一次话,并且转过之后turn[x][y]+1依然比turn[xx][yy]大的话,也不符合  
        if(dir != -1 && i != dir && turn[xx][yy] < turn[x][y]+1) {
            continue;//剪枝是搜索最最难的地方,也是核心点
        }
        if(dir != -1 && i != dir) {
            turn[xx][yy]=turn[x][y]+1;//转弯,更新turn
        }
        else {
            turn[xx][yy] = turn[x][y];
        }  
        Map[xx][yy] = '*';        //如果这里能走,就把这里变成不能走,然后再从这里开始递归,其实就是起到vis[][] 的作用,会用vis的话就不用追究了  
        DFS(xx,yy,i);  
        Map[xx][yy] = '.';        //这里再变成'.',回溯! 
        if(1 == flag) {
            return ;
        }
    } 

}  


int main()  
{  
    int x1, y1;
    scanf("%d%d", &m,&n);
    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j) {
            scanf(" %c", &Map[i][j]);
            turn[i][j] = MAX;//用于记录转弯次数 
        }
    }

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

    turn[x1][y1] = 0;
    DFS(x1, y1, -1);

    if (1 == flag) {
        printf("yes\n"); 
    }
    else {
         printf("no\n"); 
    }
    return 0;
}  

有不懂的 ,欢迎留言交流~

猜你喜欢

转载自blog.csdn.net/breakpoints_/article/details/80402544