【C语言——递归】迷宫问题

简单迷宫

/*
 * @Author: Xyh4ng
 * @Date: 2022-09-29 19:16:15
 * @LastEditors: error: git config user.name & please set dead value or install git
 * @LastEditTime: 2022-10-03 22:14:52
 * @Description: Easy Maze Question
 * Copyright (c) 2022 by Xyh4ng 503177404@qq.com, All Rights Reserved.
 */

/*
 * 问题描述:
 * 输入两个整数,分别表示二维数组的行数,列数。再输入相应的数组,其中的1表示墙壁,0表示可以走的路。
 * 数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。例如:
 * 输入:5 5
 *      0 1 0 0 0
 *      0 1 1 1 0
 *      0 0 0 0 0
 *      0 1 1 1 0
 *      0 0 0 1 0
 * 输出:(0,0)(1,0)(2,0)(2,1)(2,2)(2,3(2,4)(3,4)(4,4)
 */

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

typedef struct NodePosition
{
    int row;
    int col;
    int up;
    int down;
    int left;
    int right;
} NodePosition;

typedef struct StackNode
{
    struct StackNode *next;
    NodePosition nodePos;
} StackNode, *StackNodePtr;

typedef struct PosStack
{
    int length;
    StackNodePtr top;
} PosStack;

int CheckPass(NodePosition pos, int *mapPtr, int *flag);
void PushStack(PosStack *ps, NodePosition pos);
int PopStack(PosStack *ps, NodePosition *posPtr);
void FindPath(NodePosition pos, int *mapPtr, PosStack *ps, int *flag);

int mapRow = 0, mapCol = 0;

int main()
{
    scanf("%d %d", &mapRow, &mapCol);
    int *mapPtr = (int *)malloc(sizeof(int *) * mapRow * mapCol); // map指针
    int *flag = (int *)malloc(sizeof(int *) * mapRow * mapCol);   // 标记之前是否到过该点
    for (int i = 0; i < mapRow; i++)
    {
        for (int j = 0; j < mapCol; j++)
        {
            scanf("%d", mapPtr + mapRow * i + j);
            *(flag + mapRow * i + j) = 0;
        }
    }
    for (int i = 0; i < mapRow; i++)
    {
        for (int j = 0; j < mapCol; j++)
        {
            printf("%d", *(mapPtr + mapRow * i + j));
        }
        printf("\n");
    }

    /******************************************************** start ********************************************************/
    // 初始化起始节点
    NodePosition pos;
    pos.row = pos.col = 0;
    pos.left = pos.up = 1;
    pos.right = pos.down = 0;

    // 初始化节点栈
    PosStack *ps = (PosStack *)malloc(sizeof(PosStack *));
    ps->length = 0;
    ps->top = (StackNodePtr)malloc(sizeof(StackNodePtr));

    FindPath(pos, mapPtr, ps, flag);
    if (ps->length)
    {
        while (ps->length)
        {
            NodePosition *posPtr = (NodePosition *)malloc(sizeof(NodePosition *));
            PopStack(ps, posPtr);
            printf("(%d, %d)", posPtr->row, posPtr->col);
        }
    }
    return 0;
}

int CheckPass(NodePosition pos, int *mapPtr, int *flag)
{
    if (pos.row >= 0 &&
        pos.row < mapRow &&
        pos.col >= 0 &&
        pos.col < mapCol &&
        *(mapPtr + mapRow * pos.row + pos.col) == 0 &&
        *(flag + mapRow * pos.row + pos.col) == 0)
        return 1;
    return 0;
}

void PushStack(PosStack *ps, NodePosition pos)
{
    StackNodePtr stackNode = (StackNodePtr)malloc(sizeof(StackNodePtr));
    stackNode->nodePos = pos;
    stackNode->next = ps->top;
    ps->top = stackNode;
    ps->length++;
}

int PopStack(PosStack *ps, NodePosition *posPtr)
{
    if (ps->length == 0)
    {
        printf("PosStack is empty");
        return 0;
    }
    StackNodePtr q = ps->top;
    *posPtr = q->nodePos;
    ps->top = q->next;
    // free(q);
    ps->length--;
    return 1;
}

void FindPath(NodePosition pos, int *mapPtr, PosStack *ps, int *flag)
{
    if (CheckPass(pos, mapPtr, flag))
    {
        *(flag + mapRow * pos.row + pos.col) = 1;
        // 判断是否结束
        if (pos.row == mapRow - 1 && pos.col == mapCol - 1)
        {
            // 将终点节点入栈
            PushStack(ps, pos);
            return;
        }
        // 选择进入下一方向节点
        NodePosition pos_new;
        pos_new.left = pos_new.right = pos_new.down = pos_new.up = 0;
        if (pos.right == 0)
        {
            pos.right = 1;
            // 将可通过的节点入栈
            PushStack(ps, pos);
            pos_new.row = pos.row;
            pos_new.col = pos.col + 1;
            pos_new.left = 1;
            FindPath(pos_new, mapPtr, ps, flag);
        }
        else if (pos.down == 0)
        {
            pos.down = 1;
            // 将可通过的节点入栈
            PushStack(ps, pos);
            pos_new.row = pos.row + 1;
            pos_new.col = pos.col;
            pos_new.up = 1;
            FindPath(pos_new, mapPtr, ps, flag);
        }
        else if (pos.left == 0)
        {
            pos.left = 1;
            // 将可通过的节点入栈
            PushStack(ps, pos);
            pos_new.row = pos.row;
            pos_new.col = pos.col - 1;
            pos_new.right = 1;
            FindPath(pos_new, mapPtr, ps, flag);
        }
        else if (pos.up == 0)
        {
            pos.up = 1;
            // 将可通过的节点入栈
            PushStack(ps, pos);
            pos_new.row = pos.row - 1;
            pos_new.col = pos.col;
            pos_new.down = 1;
            FindPath(pos_new, mapPtr, ps, flag);
        }
        // 都无法走则说明此节点不通
        else
        {
            NodePosition *posPtr = (NodePosition *)malloc(sizeof(NodePosition *));
            if (PopStack(ps, posPtr))
            {
                *(flag + mapRow * (*posPtr).row + (*posPtr).col) = 0;
                FindPath(*posPtr, mapPtr, ps, flag);
            }
            else
                return;
        }
    }
    else
    {
        // 将之前的节点出栈
        NodePosition *posPtr = (NodePosition *)malloc(sizeof(NodePosition *));
        if (PopStack(ps, posPtr))
        {
            *(flag + mapRow * (*posPtr).row + (*posPtr).col) = 0;
            FindPath(*posPtr, mapPtr, ps, flag);
        }
        else
            return;
    }
}

地下迷宫

/*
 * @Author: Xyh4ng
 * @Date: 2022-10-03 21:35:28
 * @LastEditors: Xyh4ng
 * @LastEditTime: 2022-10-03 22:48:28
 * @Description:
 * Copyright (c) 2022 by Xyh4ng 503177404@qq.com, All Rights Reserved.
 */

/*
 * 问题描述:
 * 输入两个整数,分别表示二维数组的行数,列数。再输入相应的数组,其中的1表示墙壁,0表示可以走的路。
 * 数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。例如:
 * 输入:4 4
 *      10
 *      0, 1, 1, 0,
 *      0, 0, 1, 0,
 *      1, 0, 0, 0,
 *      1, 1, 0, 0
 * 输出:(0,0),(1,0),(1,1),(2,1),(2,2),(2,3),(1,3),(0,3)
 */

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

typedef struct NodePosition
{
    int row;
    int col;
    int left;
    int right;
    int up;
    int down;
    int lives;
} NodePosition;

typedef struct StackNode
{
    struct StackNode *next;
    NodePosition nodePos;
} StackNode, *StackNodePtr;

typedef struct PositionStack
{
    StackNodePtr top;
    int length;
} PositionStack;

int CheckPass(NodePosition pos, int *mapPtr, int *flag);
void PushStack(PositionStack *ps, NodePosition pos);
int PopStack(PositionStack *ps, NodePosition *posPtr);
void FindPath(NodePosition pos, int *mapPtr, PositionStack *ps, int *flag);

int mapRow = 4;
int mapCol = 4;
int frogLives = 10;

int main()
{
    // printf("Enter the map's row and col:\n");
    // scanf("%d %d", &mapRow, &mapCol);
    // printf("Enter the frog's lives:\n");
    // scanf("%d", frogLives);

    int *mapPtr = (int *)malloc(sizeof(int *) * mapRow * mapCol);
    int *flag = (int *)malloc(sizeof(int *) * mapRow * mapCol); // 标记之前是否到过该点
    // printf("Enter the maps array:\n");
    // for (int i = 0; i < mapRow; i++)
    // {
    //     for (int j = 0; j < mapCol; j++)
    //     {
    //         scanf("%d", mapPtr + mapRow * i + j);
    //     }
    // }
    // for (int i = 0; i < mapRow; i++)
    // {
    //     for (int j = 0; j < mapCol; j++)
    //     {
    //         printf("%d", *(mapPtr + mapRow * i + j));
    //     }
    //     printf("\n");
    // }

    int map[4][4] = {{0, 1, 1, 0},
                     {0, 0, 1, 0},
                     {1, 0, 0, 0},
                     {1, 1, 0, 0}};
    for (int i = 0; i < mapRow; i++)
    {
        for (int j = 0; j < mapCol; j++)
        {
            *(mapPtr + mapRow * i + j) = map[i][j];
            *(flag + mapRow * i + j) = 0;
        }
    }
    for (int i = 0; i < mapRow; i++)
    {
        for (int j = 0; j < mapCol; j++)
        {
            printf("%d", *(mapPtr + mapRow * i + j));
        }
        printf("\n");
    }

    /******************************************************** start ********************************************************/
    // 初始化起始节点
    NodePosition pos;
    pos.row = pos.col = 0;
    pos.left = pos.up = 1;
    pos.right = pos.down = 0;
    pos.lives = frogLives;

    // 初始化节点栈
    PositionStack *ps = (PositionStack *)malloc(sizeof(PositionStack *));
    ps->length = 0;
    ps->top = (StackNodePtr)malloc(sizeof(StackNodePtr));
    FindPath(pos, mapPtr, ps, flag);

    if (ps->length)
    {
        while (ps->length)
        {
            NodePosition *posPtr = (NodePosition *)malloc(sizeof(NodePosition *));
            PopStack(ps, posPtr);
            printf("(%d, %d)", posPtr->row, posPtr->col);
        }
    }
    return 0;
}

int CheckPass(NodePosition pos, int *mapPtr, int *flag)
{
    if (pos.row >= 0 &&
        pos.row < mapRow &&
        pos.col >= 0 &&
        pos.col < mapCol &&
        *(mapPtr + mapRow * pos.row + pos.col) == 0 &&
        *(flag + mapRow * pos.row + pos.col) == 0)
        return 1;
    else
        return 0;
}

void PushStack(PositionStack *ps, NodePosition pos)
{
    StackNodePtr stackNode = (StackNodePtr)malloc(sizeof(StackNodePtr));
    stackNode->nodePos = pos;
    stackNode->next = ps->top;
    ps->top = stackNode;
    ps->length++;
}

int PopStack(PositionStack *ps, NodePosition *posPtr)
{
    if (ps->length == 0)
    {
        printf("PosStack is empty");
        return 0;
    }
    StackNodePtr q = ps->top;
    *posPtr = q->nodePos;
    ps->top = q->next;
    // free(q);
    ps->length--;
    return 1;
}

void FindPath(NodePosition pos, int *mapPtr, PositionStack *ps, int *flag)
{
    if (CheckPass(pos, mapPtr, flag))
    {
        *(flag + mapRow * pos.row + pos.col) = 1;
        // 判断是否到达终点
        if (pos.row == 0 && pos.col == mapCol - 1)
        {
            // 将终点节点入栈
            PushStack(ps, pos);
            return;
        }
        // 选择进入下一方向节点
        NodePosition pos_new;
        pos_new.left = pos_new.right = pos_new.up = pos_new.down = 0;
        if (pos.right == 0)
        {
            pos.right = 1;
            // 将可通过的节点入栈
            PushStack(ps, pos);
            pos_new.row = pos.row;
            pos_new.col = pos.col + 1;
            pos_new.left = 1;
            if ((pos.lives - 1) >= 0)
            {
                pos_new.lives = pos.lives - 1;
                FindPath(pos_new, mapPtr, ps, flag);
            }
            // 判断体力值是否耗尽
            else
            {
                printf("Can not escape\n");
                return;
            }
        }
        else if (pos.down == 0)
        {
            pos.down = 1;
            // 将可通过的节点入栈
            PushStack(ps, pos);
            pos_new.row = pos.row + 1;
            pos_new.col = pos.col;
            pos_new.up = 1;
            pos_new.lives = pos.lives;
            FindPath(pos_new, mapPtr, ps, flag);
        }
        else if (pos.left == 0)
        {
            pos.left = 1;
            // 将可通过的节点入栈
            PushStack(ps, pos);
            pos_new.row = pos.row;
            pos_new.col = pos.col - 1;
            pos_new.right = 1;
            if ((pos.lives - 1) >= 0)
            {
                pos_new.lives = pos.lives - 1;
                FindPath(pos_new, mapPtr, ps, flag);
            }
            // 判断体力值是否耗尽
            else
            {
                printf("Can not escape\n");
                return;
            }
        }
        else if (pos.up == 0)
        {
            pos.up = 1;
            // 将可通过的节点入栈
            PushStack(ps, pos);
            pos_new.row = pos.row - 1;
            pos_new.col = pos.col;
            pos_new.down = 1;
            if ((pos.lives - 3) >= 0)
            {
                pos_new.lives = pos.lives - 3;
                FindPath(pos_new, mapPtr, ps, flag);
            }
            // 判断体力值是否耗尽
            else
            {
                printf("Can not escape\n");
                return;
            }
        }
        // 都无法走则说明此节点不通
        else
        {
            NodePosition *posPtr = (NodePosition *)malloc(sizeof(NodePosition *));
            if (PopStack(ps, posPtr))
            {
                *(flag + mapRow * (*posPtr).row + (*posPtr).col) = 0;
                FindPath(*posPtr, mapPtr, ps, flag);
            }
            else
                return;
        }
    }
    else
    {
        NodePosition *posPtr = (NodePosition *)malloc(sizeof(NodePosition *));
        if (PopStack(ps, posPtr))
        {
            *(flag + mapRow * (*posPtr).row + (*posPtr).col) = 0;
            FindPath(*posPtr, mapPtr, ps, flag);
        }
        else
            return;
    }
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值