【学习总结】240202_数据结构与算法(八)

  • 《大话数据结构》读书笔记+课程补充
  •  每日一个例题示范

一、读书笔记+课程补充

     今天来汇集一下代码中的一些常见调试步骤和潜在问题:

  1. 确保包含函数所需的库。

  2. 常量和数组:确保常量适合实际问题,并且数组的大小正确。

  3. 输入读数:验证输入是否被正确读取。确保值在可接受的范围内。

  4. 内存溢出:检查相关值是否不超过数组大小。队列数组大小确定。

  5. 数组边界:确保数组索引不会越界。否则可能会导致内存损坏和未定义的行为。

  6. 循环条件:验证循环 ( 和 ) 是否具有正确的条件,并且不会导致无限循环。

  7. 调试输出:在代码中的关键点(例如,循环前后、内部条件)插入 print 语句,以查看程序可能失败的地方。

  8. 编译器警告:在编译过程中检查是否有任何编译器警告。解决这些问题以确保正确执行代码。

  9. 初始化:确保所有变量在使用前都已正确初始化。

  10. 算法逻辑:确保使用的算法对于您的问题是正确的。例如 BFS(广度优先搜索)。

二、每日一个例题示范

带有无敌点的迷宫游戏

题目描述

小明在玩一款迷宫游戏,在游戏中他要控制自己的角色离开一间由 �×�N×N 个格子组成的二维迷宫。

小明的起始位置在左上角,他需要到达右下角的格子才能离开迷宫。

每一步,他可以移动到上下左右相邻的格子中(前提是目标格子可以经过)。

迷宫中有些格子小明可以经过,我们用 . 表示;

有些格子是墙壁,小明不能经过,我们用 # 表示。

此外,有些格子上有陷阱,我们用 X 表示。除非小明处于无敌状态,否则不能经过。

有些格子上有无敌道具,我们用 % 表示。

当小明第一次到达该格子时,自动获得无敌状态,无敌状态会持续 �K 步。

之后如果再次到达该格子不会获得无敌状态了。

处于无敌状态时,可以经过有陷阱的格子,但是不会拆除 / 毁坏陷阱,即陷阱仍会阻止没有无敌状态的角色经过。

给定迷宫,请你计算小明最少经过几步可以离开迷宫。

输入格式

第一行包含两个整数 �N 和 �K。(1≤�≤1000,1≤�≤10)(1≤N≤1000,1≤K≤10)。

以下 �N 行包含一个 �×�N×N 的矩阵。

矩阵保证左上角和右下角是 .

输出格式

一个整数表示答案。如果小明不能离开迷宫,输出 −1−1。

#include 
#include 
#include 

#define MAX_N 1005

typedef struct {
    int x;
    int y;
    int steps;
    bool invincible;
} Position;

char maze[MAX_N][MAX_N];
bool visited[MAX_N][MAX_N][11]; 
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};

int main() {
    int N, K;
    scanf("%d %d", &N, &K);
    for (int i = 0; i < N; ++i) {
        scanf("%s", maze[i]);
    }

    Position queue[MAX_N * MAX_N * 11];  
    int front = 0, rear = 0;

    queue[rear++] = (Position){0, 0, 0, false};
    visited[0][0][0] = true;

    while (front < rear) {
        Position current = queue[front++];

        if (current.x == N - 1 && current.y == N - 1) {
            printf("%d\n", current.steps);
            return 0;
        }

        for (int i = 0; i < 4; ++i) {
            int nx = current.x + dx[i];
            int ny = current.y + dy[i];

            if (nx >= 0 && nx < N && ny >= 0 && ny < N) {
                if (maze[nx][ny] == '#' || (maze[nx][ny] == 'X' && !current.invincible)) {
                    continue;
                }

                bool next_invincible = current.invincible;
                if (maze[nx][ny] == '%' && !visited[nx][ny][current.invincible]) {
                    next_invincible = true;
                }

                if (!visited[nx][ny][next_invincible]) {
                    visited[nx][ny][next_invincible] = true;
                    queue[rear++] = (Position){nx, ny, current.steps + 1, next_invincible};
                }
            }
        }
    }

    printf("-1\n"); 
    return 0;
}

分析:

使用BFS(广度优先搜索)算法搜索迷宫中的最短路径。当队列不为空时,取出队首元素,判断是否到达了终点,如果是则输出步数并结束程序;否则对当前位置的四个相邻位置进行处理,如果某个相邻位置可以到达且未被访问过,则将其加入队列中。

在处理相邻位置时,需要考虑墙壁、陷阱、无敌状态等情况。如果遇到墙壁或者陷阱但未处于无敌状态,则无法通过,继续搜索其他方向;如果遇到无敌道具,则获得无敌状态。

你可能感兴趣的:(学习)