- 《大话数据结构》读书笔记+课程补充
- 每日一个例题示范
一、读书笔记+课程补充
今天来汇集一下代码中的一些常见调试步骤和潜在问题:
-
确保包含函数所需的库。
-
常量和数组:确保常量适合实际问题,并且数组的大小正确。
-
输入读数:验证输入是否被正确读取。确保值在可接受的范围内。
-
内存溢出:检查相关值是否不超过数组大小。队列数组大小确定。
-
数组边界:确保数组索引不会越界。否则可能会导致内存损坏和未定义的行为。
-
循环条件:验证循环 ( 和 ) 是否具有正确的条件,并且不会导致无限循环。
-
调试输出:在代码中的关键点(例如,循环前后、内部条件)插入 print 语句,以查看程序可能失败的地方。
-
编译器警告:在编译过程中检查是否有任何编译器警告。解决这些问题以确保正确执行代码。
-
初始化:确保所有变量在使用前都已正确初始化。
-
算法逻辑:确保使用的算法对于您的问题是正确的。例如 BFS(广度优先搜索)。
二、每日一个例题示范
带有无敌点的迷宫游戏
题目描述
小明在玩一款迷宫游戏,在游戏中他要控制自己的角色离开一间由 �×�N×N 个格子组成的二维迷宫。
小明的起始位置在左上角,他需要到达右下角的格子才能离开迷宫。
每一步,他可以移动到上下左右相邻的格子中(前提是目标格子可以经过)。
迷宫中有些格子小明可以经过,我们用 .
表示;
有些格子是墙壁,小明不能经过,我们用 #
表示。
此外,有些格子上有陷阱,我们用 X
表示。除非小明处于无敌状态,否则不能经过。
有些格子上有无敌道具,我们用 %
表示。
当小明第一次到达该格子时,自动获得无敌状态,无敌状态会持续 �K 步。
之后如果再次到达该格子不会获得无敌状态了。
处于无敌状态时,可以经过有陷阱的格子,但是不会拆除 / 毁坏陷阱,即陷阱仍会阻止没有无敌状态的角色经过。
给定迷宫,请你计算小明最少经过几步可以离开迷宫。
输入格式
第一行包含两个整数 �N 和 �K。(1≤�≤1000,1≤�≤10)(1≤N≤1000,1≤K≤10)。
以下 �N 行包含一个 �×�N×N 的矩阵。
矩阵保证左上角和右下角是 .
。
输出格式
一个整数表示答案。如果小明不能离开迷宫,输出 −1−1。
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#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(广度优先搜索)算法搜索迷宫中的最短路径。当队列不为空时,取出队首元素,判断是否到达了终点,如果是则输出步数并结束程序;否则对当前位置的四个相邻位置进行处理,如果某个相邻位置可以到达且未被访问过,则将其加入队列中。
在处理相邻位置时,需要考虑墙壁、陷阱、无敌状态等情况。如果遇到墙壁或者陷阱但未处于无敌状态,则无法通过,继续搜索其他方向;如果遇到无敌道具,则获得无敌状态。