厦大小学期C语言程序设计实践(三)

所有实践项目的源程序可到我的Github上下载:https://github.com/liulizhi1996/C-Programming-Practice-in-short-semester


问题描述:

以一个n的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍,设计一个程序,对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。

对于本问题需用栈实现“穷举求解”算法,即:从入口出发,顺着某一个方向进行探索,若能走通,则继续往前进;否则沿着原路退回,换一个方向继续探索,直至出口位置,求得一条通路。加入所有可能的通路都探索到而未能到达出口,则所设定的迷宫没有通路。迷宫数据是一个n阶矩阵用二维数组存储,起点为(1,1),终点为(n,n),再在迷宫外围加上一层围墙(默认为1,不需用户输入,用户只需输入迷宫数据即可),对于迷宫中每个数据都有四个方向可通。

具体实现算法的函数及要点如下:初始化栈,销毁栈,清空栈,判栈空,取栈顶元素,插入新的栈顶元素,删除栈顶元素,从栈底到栈顶依次访问栈中的每个结点,最重要的就是要判断迷宫的通路。

从迷宫的入口到出口找出一条通路的算法如下:设定当前位置的初值为入口位置;

   do{

       若当前位置可通,

       则{将当前位置插入栈顶;

                                若该位置是出口位置,则算法结束;

                                否则切换当前位置的东邻方块为新的位置;

                     }

       否则{回到当前位置的前一个位置,判断是否可通(类似于上面算法)

                                ……

        }

      }while(栈不空);

若栈不空且栈顶位置尚有其他方向未被探索,

则设定新的当前位置为: 沿顺时针方向旋转

找到的栈顶位置的下一相邻块;

若栈不空但栈顶位置的四周均不可通,

则{删去栈顶位置;// 从路径中删去该通道块

若栈不空,则重新测试新的栈顶位置,

直至找到一个可通的相邻块或出栈至栈空;

若栈空,则表明迷宫通路。

最后根据栈储存的数据输出迷宫径即可。


stack.h

#ifndef STACK_H
#define STACK_H

struct Pos
{
    int x;
    int y;
};

struct Node
{
    struct Pos pos;
    int direction;
    struct Node *next;
};

void init(struct Node **head);
void destroy(struct Node **head);
void clear(struct Node *head);
int is_empty(struct Node *head);
int top(struct Node *head, struct Pos *pos, int *direction);
void push(struct Node *head, struct Pos pos, int direction);
int pop(struct Node *head, struct Pos *pos, int *direction);
void traverse(struct Node *head);

#endif //STACK_H
stack.cpp

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

void init(struct Node **head)
{
    *head = (struct Node *)malloc(sizeof(struct Node));
    (*head)->next = NULL;
}

void destroy(struct Node **head)
{
    struct Node *p, *q;

    p = *head;
    if (*head)
        q = (*head)->next;
    while (p)
    {
        free(p);
        p = q;
        if (q)
            q = q->next;
    }
    *head = NULL;
}

void clear(struct Node *head)
{
    struct Node *p, *q;

    if (head)
    {
        destroy(&(head->next));
        head->next = NULL;
    }
}

int is_empty(struct Node *head)
{
    if (head && head->next)
        return 0;
    else
        return 1;
}

int top(struct Node *head, struct Pos *pos, int *direction)
{
    if (!is_empty(head))
    {
        pos->x = head->next->pos.x;
        pos->y = head->next->pos.y;
        *direction = head->next->direction;
        return 1;
    }
    else
        return 0;
}

void push(struct Node *head, struct Pos pos, int direction)
{
    struct Node *p = (struct Node *)malloc(sizeof(struct Node));
    p->pos.x = pos.x;
    p->pos.y = pos.y;
    p->direction = direction;
    p->next = head->next;
    head->next = p;
}

int pop(struct Node *head, struct Pos *pos, int *direction)
{
    if (!is_empty(head))
    {
        struct Node *p = head->next;
        pos->x = p->pos.x;
        pos->y = p->pos.y;
        *direction = p->direction;
        head->next = p->next;
        free(p);
        return 1;
    }
    else
        return 0;
}

void recursive_traverse(struct Node *p)
{
    if (p)
    {
        recursive_traverse(p->next);
        printf("(%d, %d)->", p->pos.x, p->pos.y);
    }
}

void traverse(struct Node *head)
{
    if (!is_empty(head))
    {
        recursive_traverse(head->next);
    }
}
main.cpp
#include <stdio.h>
#include <stdlib.h>
#include "stack.h"

int maze[30][30] = { 0 };
struct Node *stack;
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};

void solve_maze(int N)
{
    struct Pos pos;
    int direction;
    pos.x = 1, pos.y = 1, direction = -1;

    push(stack, pos, direction);
    while (!is_empty(stack))
    {
        pop(stack, &pos, &direction);
        direction++;

        while (direction < 4)
        {
            if (maze[pos.x+dx[direction]][pos.y+dy[direction]] == 0)
            {
                push(stack, pos, direction);
                maze[pos.x][pos.y] = -1;
                pos.x = pos.x + dx[direction];
                pos.y = pos.y + dy[direction];
                if (pos.x == N && pos.y == N)
                {
                    printf("Path: ");
                    traverse(stack);
                    printf("(%d, %d)\n", N, N);
                    return;
                }
                else
                    direction = 0;
            }
            else
                direction++;
        }
    }

    printf("No Path!\n");
}

int main()
{
    int N;

    printf("Please enter the size of maze: ");
    scanf("%d", &N);
    for (int i = 0; i <= N+1; ++i)
    {
        maze[0][i] = 1;
        maze[N+1][i] = 1;
        maze[i][0] = 1;
        maze[i][N+1] = 1;
    }
    printf("Please enter the maze: \n");
    for (int i = 1; i <= N; ++i)
    {
        for (int j = 1; j <= N; ++j)
        {
            scanf("%d", &maze[i][j]);
        }
    }

    init(&stack);
    solve_maze(N);
    destroy(&stack);

    return 0;
}
测试数据:

Test 1:
8
0 0 1 0 0 0 1 0
0 0 1 0 0 0 1 0
0 0 0 0 1 1 0 0
0 1 1 1 0 0 0 0
0 0 0 1 0 0 0 0
0 1 0 0 0 1 0 0
0 1 1 1 0 1 1 0
1 0 0 0 0 0 0 0

Test 2:
2
1 1
1 1

Test 3:
5
0 1 1 1 1
0 0 0 1 1
1 1 1 1 0
0 0 0 0 1
1 1 0 1 0

Test 4:
3
0 0 1
0 1 1
0 0 1

Test 5:
10
0 0 1 0 0 0 0 1 0 1
1 0 1 0 1 1 0 1 1 0
1 0 0 0 1 1 0 0 0 1
0 1 0 1 1 0 0 1 1 1
0 1 0 0 1 1 0 1 0 0
1 0 1 0 1 1 0 0 1 0
0 1 1 0 0 0 1 0 1 1
0 1 0 1 1 0 0 0 0 0
0 1 1 0 0 1 1 1 1 0
1 0 1 0 1 1 0 0 1 0

Test 6:
8
0 0 1 1 1 0 1 0
1 0 0 1 1 1 0 1
1 1 0 0 0 0 0 1
1 1 0 1 1 1 0 1
1 1 0 1 1 1 0 1
1 1 0 0 0 0 0 1
1 1 1 1 1 1 0 1
1 1 0 0 0 0 0 0

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
厦大c语言上机1370题是厦门大学计算机系开设的一门课程考试题目。这道题目主要考察学生对于C语言的掌握程度以及编写程序的能力。根据我对于这道题目的理解,我将尽力回答这个题目。 首先,题目要求我们编写一个C程序,实现对输入的多个正整数进行排序,并按照升序输出。在解决这个问题时,我们可以使用一种常见的排序算法,例如冒泡排序、选择排序或者插入排序。 具体实现上机1370的方法如下: 1. 首先,我们需要利用scanf函数从用户输入中读取多个正整数,并将其存储在一个数组中。 2. 接下来,我们可以选择适合的排序算法对这个数组进行排序。这里我们以冒泡排序来进行举例,它的实现思路是从数组的第一个元素开始,依次比较相邻的两个元素,如果顺序不对则交换位置,这样通过多次迭代,最终达到排序的效果。 3. 最后,我们使用printf函数按照升序输出排序后的数组元素。 例如,对于输入的正整数序列[5, 2, 4, 3, 1],经过冒泡排序后,输出的结果为[1, 2, 3, 4, 5]。 在完成程序编写后,我们可以通过编译器进行编译,然后使用输入数据进行测试。如果程序能够正确输出按升序排列的正整数序列,则说明我们顺利完成了上机1370的任务。 总之,厦大c语言上机1370题目要求我们编写一个C程序,能够实现对多个输入正整数的排序,并按照升序输出结果。正确完成这个题目可以展示我们对C语言的掌握以及程序设计的能力。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值