题解 | #迷宫问题# 一直往右走即可走出迷宫+栈的思想

迷宫问题

http://www.nowcoder.com/practice/cf24906056f4488c9ddb132f317e03bc

因为只有且仅有一条路能走出迷宫,那就用最简单,从自己的最右边一直走。最后就能走出迷宫了。

为每个点都设置5个标志,四个方向是否可以走的标志,入口方向标志。

设置一个数组栈,把第一个点作为入口,加入栈低。最up标志开始(即自己的右边开始),把能走的点都加入到栈中,当走到死胡同时,就出栈,在出栈的过程中,把死胡同做上"1"的标记,这样,在出栈的时候,对每个点的标志进行判定,能走的点,继续入栈,否则,继续出栈。当终点入栈,则栈就是我们用这个方法走出的一条起点到终点的路径。

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

typedef enum { UP = 1, RIGHT, DOWN, LEFT, ZERO } Entry_e;

typedef struct {
    int  pos_row;
    int  pos_col;
    int  entry;
    bool up;
    bool down;
    bool right;
    bool left;
} Node_t;

int **new_array(int row, int col)
{
    int **array = calloc(row, sizeof(int *));
    for (int i = 0; i < row; i++) {
        array[i] = calloc(col, sizeof(int));
    }
    return array;
}

void delete_array(int **array, int row)
{
    for (int i = 0; i < row; i++) {
        free(array[i]);
    }
    free(array);
}

void get_nums(int **array, int row, int col)
{
    for (int i = 0; i < row; i++) {
        for (int j = 0; j < col; j++) {
            scanf("%d", &array[i][j]);
        }
    }
}

void print_nums(int **array, int row, int col)
{
    for (int i = 0; i < row; i++) {
        for (int j = 0; j < col; j++) {
            printf("%d ", array[i][j]);
        }
        printf("\n");
    }
}

bool is_in_table(int pos_row, int pos_rol, int **array, int row, int rol)
{
    if (pos_row >= 0 && pos_row < row && pos_rol >= 0 && pos_rol < rol) {
        if (array[pos_row][pos_rol] != 1) {
            return true;
        }
    }
    return false;
}

void scan_around(Node_t *node, int **array, int rowMax, int colMax)
{
    int row           = node->pos_row;
    int col           = node->pos_col;
    int pos_up_row    = row - 1;
    int pos_up_col    = col;
    int pos_down_row  = row + 1;
    int pos_down_col  = col;
    int pos_right_row = row;
    int pos_right_col = col + 1;
    int pos_left_row  = row;
    int pos_left_col  = col - 1;
    node->up          = is_in_table(pos_up_row, pos_up_col, array, rowMax, colMax);
    node->down        = is_in_table(pos_down_row, pos_down_col, array, rowMax, colMax);
    node->right       = is_in_table(pos_right_row, pos_right_col, array, rowMax, colMax);
    node->left        = is_in_table(pos_left_row, pos_left_col, array, rowMax, colMax);
}

void print_node(Node_t *node)
{
    printf("row:%d, col:%d, entry:%d\n", node->pos_row, node->pos_col, node->entry);
    printf("up:%d, right:%d, down:%d, left:%d\n", node->up, node->right, node->down, node->left);
}

bool traverse(int **array, int row, int col, Node_t *nodes, int *index)
{
    Node_t *node = &nodes[*index];
    // print_node(node);
    if (node->entry != UP && node->up) {
        if (array[node->pos_row - 1][node->pos_col] == 0) {
            (*index)++;
            Node_t *nn  = &nodes[*index];
            nn->entry   = DOWN;
            nn->pos_row = node->pos_row - 1;
            nn->pos_col = node->pos_col;
            scan_around(nn, array, row, col);
        }
    } else if (node->entry != RIGHT && node->right) {
        if (array[node->pos_row][node->pos_col + 1] == 0) {
            (*index)++;
            Node_t *nn  = &nodes[*index];
            nn->entry   = LEFT;
            nn->pos_row = node->pos_row;
            nn->pos_col = node->pos_col + 1;
            scan_around(nn, array, row, col);
        }
    } else if (node->entry != DOWN && node->down) {
        if (array[node->pos_row + 1][node->pos_col] == 0) {
            (*index)++;
            Node_t *nn  = &nodes[*index];
            nn->entry   = UP;
            nn->pos_row = node->pos_row + 1;
            nn->pos_col = node->pos_col;
            scan_around(nn, array, row, col);
        }
    } else if (node->entry != LEFT && node->left) {
        if (array[node->pos_row][node->pos_col - 1] == 0) {
            (*index)++;
            Node_t *nn  = &nodes[*index];
            nn->entry   = RIGHT;
            nn->pos_row = node->pos_row;
            nn->pos_col = node->pos_col - 1;
            scan_around(nn, array, row, col);
        }
    } else {
        array[node->pos_row][node->pos_col] = 1;
        (*index)--;
        Node_t *nn = &nodes[*index];
        scan_around(nn, array, row, col);
    }

    // print_path(nodes, *index);
    // printf("--------------------------------\n\n");
    // sleep(1);

    if (nodes[*index].pos_row == row - 1 && nodes[*index].pos_col == col - 1) {
        return true;
    }
    return false;
}

void print_path(Node_t *nodes, int index)
{
    for (int i = 0; i <= index; i++) {
        printf("(%d,%d)\n", nodes[i].pos_row, nodes[i].pos_col);
    }
}

int main()
{
    int row = 0;
    int col = 0;
    while (scanf("%d %d", &row, &col) != EOF) {
        int **array = new_array(row, col);
        get_nums(array, row, col);
        // print_nums(array, row, col);

        Node_t *nodes    = calloc(row * col, sizeof(Node_t));
        int     index    = 0;
        nodes[0].entry   = ZERO;
        nodes[0].pos_row = 0;
        nodes[0].pos_col = 0;
        scan_around(&nodes[0], array, row, col);

        while (!traverse(array, row, col, nodes, &index)) {
            ;
        }

        print_path(nodes, index);
        delete_array(array, row);
    }
    return 0;
}
全部评论

相关推荐

bg双非本科,方向是嵌入式。这次秋招一共拿到了&nbsp;8&nbsp;个&nbsp;offer,最高年包&nbsp;40w,中间也有一段在海康的实习经历,还有几次国家级竞赛。写这篇不是想证明什么,只是想把自己走过的这条路,尽量讲清楚一点,给同样背景的人一个参考。一、我一开始也很迷茫刚决定走嵌入式的时候,其实并没有一个特别清晰的规划。网上的信息很零散,有人说一定要懂底层,有人说项目更重要,也有人建议直接转方向。很多时候都是在怀疑:1.自己这种背景到底有没有机会2.现在学的东西到底有没有用3.是不是已经开始晚了这些问题,我当时一个都没答案。二、现在回头看,我主要做对了这几件事第一,方向尽早确定,但不把自己锁死。我比较早就确定了嵌入式这个大方向,但具体做哪一块,是在项目、竞赛和实习中慢慢调整的,而不是一开始就给自己下结论。第二,用项目和竞赛去“证明能力”,而不是堆技术名词。我不会刻意追求学得多全面,而是确保自己参与的每个项目,都能讲清楚:我负责了什么、遇到了什么问题、最后是怎么解决的。第三,尽早接触真实的工程环境。在海康实习的那段时间,对我触动挺大的。我开始意识到,企业更看重的是代码结构、逻辑清晰度,以及你能不能把事情说清楚,而不只是会不会某个知识点。第四,把秋招当成一个需要长期迭代的过程。简历不是一次写完的,面试表现也不是一次就到位的。我会在每次面试后复盘哪些问题没答好,再针对性补。三、我踩过的一些坑现在看也挺典型的:1.一开始在底层细节上纠结太久,投入产出比不高2.做过项目,但前期不会总结,导致面试表达吃亏3.早期有点害怕面试,准备不充分就去投这些弯路走过之后,才慢慢找到节奏。四、给和我背景相似的人一点建议如果你也是双非,准备走嵌入式,我觉得有几件事挺重要的:1.不用等“准备得差不多了”再投2.项目一定要能讲清楚,而不是做完就算3.不要只盯着技术,多关注表达和逻辑很多时候,差的不是能力,而是呈现方式。五、写在最后这篇总结不是标准答案,只是我个人的一次复盘。后面我会陆续把自己在嵌入式学习、竞赛、实习和秋招中的一些真实经验拆开来讲,希望能对后来的人有点帮助。如果你正好也在这条路上,希望你能少走一点弯路。
x_y_z1:蹲个后续
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务