HDU1010

题目一直说的是时间,因为一秒一步,实际上就是在找到出口时是否走了恰好走了T步,注意此时走的路径不一定是最短路径,有可能饶了几步才刚好T步到达终点

简单的DFS,标准的迷宫求解型的题目,输入时用变量记录下开始的坐标,终点的坐标。

对于开始站的位置在刚开始就要记录一下,因为在深搜过程中开始站的地方已经不能走了。

利用一个flag在递归过程中进行简单的剪枝,因为在找到正确答案后就不需要再增加递归深度了。

注意标记与回溯,边界判断,以及边界和标记的判断顺序,防止数组越界访问

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

char a[10][10];
int vis[10][10];
int sizev = sizeof(vis);
int flag;
int s_i, s_j, d_i, d_j;
int M, N, T;
void f(int i, int j, int dep)
{
    if (i == d_i && j == d_j) {          ///递归出口
        if (T == dep) {            
            flag = 1;                ///当找到door的坐标,并且dep和要求的时间相等时,找到出口,标记flag以后不再增加递归深度
        }
        return ;
    }
    ///对于当前位置的上下左右进行DFS
    ///注意&&的先后顺序和短路效应
    ///写成!flag && !vis[i - 1][j] && i - 1 >= 0会因为vis在i - 1 < 0时越界访问而出错,i + 1, j - 1, j + 1同样注意越界问题
    if (!flag && i - 1 >= 0 && !vis[i - 1][j]) {     
        vis[i - 1][j] = 1;         ///标记表示已经走过
        f(i - 1, j, dep + 1);
        vis[i - 1][j] = 0;       ///回溯,删除标记,为其他可能路径留出空间
    }
    if (!flag && j + 1 < M && !vis[i][j + 1]) {
        vis[i][j + 1] = 1;
        f(i, j + 1, dep + 1);
        vis[i][j + 1] = 0;
    }
    if (!flag && i + 1 < N && !vis[i + 1][j]) {
        vis[i + 1][j] = 1;
        f(i + 1, j, dep + 1);
        vis[i + 1][j] = 0;
    }
    if (!flag && j - 1 >= 0 && !vis[i][j - 1]) {
        vis[i][j - 1] = 1;
        f(i, j - 1, dep + 1);
        vis[i][j - 1] = 0;
    }
}

int main()
{
#if 0
    freopen("data.in", "r", stdin);
    freopen("data.out", "w", stdout);
#endif // 1
    int i, j;
    while (~scanf("%d%d%d", &N, &M, &T)) {
        getchar();  ///留意缓冲
        if (N == 0 && M == 0 && T == 0) break;
        memset(vis, 0, sizev);    ///初始化标记路径数组
        for (i = 0; i < N; i++) {
            for (j = 0; j < M; j++) {
                scanf("%c", &a[i][j]);
                if (a[i][j] == 'S') {
                    s_i = i;
                    s_j = j;
                    vis[i][j] = 1;    ///对于起点,开始的时候就要赋值1
                }
                if (a[i][j] == 'X') vis[i][j] = 1;  ///墙不能走
                if (a[i][j] == 'D') {
                    d_i = i;
                    d_j = j;          ///记录出口位置
                }
            }
            getchar();   ///留意缓冲
        }
        flag = 0;     ///初始化flag
        f(s_i, s_j, 0);    ///从起点开始,起点走的步数为0
        if (flag)
            printf("YES");
        else
            printf("NO");
        puts("");
    }
    return 0;
}



你可能感兴趣的:(ACM,DFS,深度搜索,hduoj)