牛客网题目链接:地下迷宫_牛客题霸_牛客网 (nowcoder.com)
#include <stdio.h>
#include <stdbool.h>
#include <assert.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
typedef struct Postion {
int row;
int col;
} PT;
typedef PT STDataType;
///
typedef struct Stack {
STDataType* a;
int top;
int capacity;//容量
} ST;
ST path;//创建路径
ST minpath;//最短路径
//初始化
void StackInit(ST* ps) {
assert(ps);
ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);
if (ps->a == NULL) {
printf("realloc fail\n");
exit(-1);
} else {
ps->capacity = 4;
ps->top = 0;
}
}
//销毁
void StackDestory(ST* ps) {
assert(ps);
free(ps->a);
ps->a = NULL;
ps->top = ps->capacity = 0;
}
//入数据
void StackPush(ST* ps, STDataType x) {
assert(ps);
//数据满了
if (ps->top == ps->capacity) {
STDataType* tmp = (STDataType*)realloc(ps->a,
ps->capacity * 2 * sizeof(STDataType));
if (tmp == NULL) {
printf("realloc fail\n");
exit(-1);
} else {
ps->a = tmp;
ps->capacity *= 2;
}
}
ps->a[ps->top] = x;
ps->top++;
}
//出数据
void StackPop(ST* ps) {
assert(ps);
//栈空了调用pop报错
assert(ps->top > 0);
ps->top--;
}
//查看栈顶元素
STDataType StackTop(ST* ps) {
assert(ps);
//栈空了调用查看报错
assert(ps->top > 0);
return ps->a[ps->top - 1];
}
//查看栈大小
int StackSize(ST* ps) {
assert(ps);
return ps->top;
}
//判断是否为空
bool StackEmpty(ST* ps) {
assert(ps);
return ps->top == 0;
}
/
//打印迷宫
void PrintMaze(int** maze, int n, int m) {
printf("\n");
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
printf("%d ", maze[i][j]);
}
printf("\n");
}
printf("\n");
}
bool IsPass(int** maze, int n, int m, PT pos) {
if (pos.row >= 0 && pos.row < n
&& pos.col >= 0 && pos.col < m
&& maze[pos.row][pos.col] == 1)
return true;
else
return false;
}
//打印路径
void PrintPath(ST* ps) {
ST rPath;
StackInit(&rPath);
//把path栈倒到另一个rpath栈中
while (!StackEmpty(ps)) {
StackPush(&rPath, StackTop(ps));
StackPop(ps);
}
while (StackSize(&rPath) > 1) {
PT top = StackTop(&rPath);
printf("[%d,%d],", top.row, top.col);
StackPop(&rPath);
}
PT top = StackTop(&rPath);
printf("[%d,%d]", top.row, top.col);
StackPop(&rPath);
StackDestory(&rPath);
}
//拷贝栈
void StackCopy(ST* ppath, ST* pcopy) {
pcopy->a = (STDataType*)malloc(sizeof(STDataType) * ppath->capacity);
memcpy(pcopy->a, ppath->a, sizeof(STDataType)*ppath->top);
pcopy->top = ppath->top;
pcopy->capacity = ppath->capacity;
}
void GetMazePath(int** maze, int n, int m, PT cur, int p) {
//入栈
StackPush(&path, cur);
//走到出口
if (cur.row == 0 && cur.col == m - 1) {
//如果找到了更短路径就更新
if (p>=0 && StackEmpty(&minpath) || StackSize(&path) < StackSize(&minpath)) {
StackDestory(&minpath);
StackCopy(&path, &minpath);
}
}
//探测cur位置的上下左右四个方向
PT next;
//先把自己改成2表示已走过
maze[cur.row][cur.col] = 2;
//上
next = cur;
next.row -= 1;
if (IsPass(maze, n, m, next)) {
GetMazePath(maze, n, m, next, p - 3);
}
//下
next = cur;
next.row += 1;
if (IsPass(maze, n, m, next)) {
GetMazePath(maze, n, m, next, p );
}
//左
next = cur;
next.col -= 1;
if (IsPass(maze, n, m, next)) {
GetMazePath(maze, n, m, next, p - 1);
}
//右
next = cur;
next.col += 1;
if (IsPass(maze, n, m, next)) {
GetMazePath(maze, n, m, next, p - 1);
}
//四个方向都不通,出栈
//恢复可走路径
maze[cur.row][cur.col] = 1;
StackPop(&path);
}
int main() {
StackInit(&path);
StackInit(&minpath);
int n;
int m;
int p;
//printf("请输入迷宫长宽、和体力值:");
while (scanf("%d %d %d", &n, &m, &p) != EOF) {
int** maze = (int**)malloc(sizeof(int*) * n);
for (int i = 0; i < n; i++) {
maze[i] = (int*)malloc(sizeof(int) * m);
}
//输入迷宫
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
scanf("%d", &maze[i][j]);
}
}
PT entry = { 0, 0 };
//PrintMaze(maze, n, m);
GetMazePath(maze, n, m, entry, p);
if (!StackEmpty(&minpath))
{
PrintPath(&minpath);
}
else
{
printf("Can not escape!");
}
//PrintMaze(maze, n, m);
StackDestory(&path);
StackDestory(&minpath);
//释放数据
for (int i = 0; i < n; i++) {
free(maze[i]);
}
free(maze);
maze = NULL;
}
return 0;
}