2023/10/30-11/1 周一到周三
忙着写作业,没空写题
迷宫问题写起来毫无头绪,所以找了一个视频来看:
【DFS深搜解决迷宫问题(原理分析+代码实现)】 https://www.bilibili.com/video/BV1bK4y1C7W2/?p=2&share_source=copy_web&vd_source=7ffbd7feaeedb3d59fb21e59435a53d8
看了一下这篇文章,懂了迷宫问题的解法
2023/11/2 周四
蓝桥杯练习2 玩具蛇
【题目描述】
小蓝有一条玩具蛇,一共有 16 节,上面标着数字 1 至 16。每一节都是一个正方形的形状。相邻的两节可以成直线或者成 90 度角。小蓝还有一个 4 × 4 的方格盒子,用于存放玩具蛇,盒子的方格上依次标着字母 A 到 P 共 16 个字母。小蓝可以折叠自己的玩具蛇放到盒子里面。他发现,有很多种方案可以将玩具蛇放进去。
下图给出了两种方案:
请帮小蓝计算一下,总共有多少种不同的方案。如果两个方案中,存在玩具蛇的某一节放在了盒子的不同格子里,则认为是不同的方案。
【题目分析】
每个空格都有可以作为起点,我们需要把起点坐标通过两个循环传进dfs函数里面。这道题和迷宫问题类似,但是这里是需要全部走满,而迷宫问题是求最小路径。
注意有个易错点:dfs递归中,length如果要加1不是用length++,用length+1。
【回溯算法的框架】
//回溯算法的实现框架
//模式一 :
//int Search(int k)
//{
// for (i = l; i <= 算符种数; i++) //搜索
// if (满足条件)
// {
// 保存结果
// if (到目的地) 输出解;
// else Search(k + 1);
// 恢复:保存结果之前的状态(回溯一步)
// }
//}
//
//模式二 :
//int Search(int k)
//{
// if (到目的地)
// 输出解;
// else
// for (i = l; i <= 算符种数; i++) //搜索
// if (满足条件)
// {
// 保存结果;
// Search(k + 1);
// 恢复:保存结果之前的状态(回溯一步) //回溯
// }
//}
这里用的是模式2,模式2比较多人使用
【参考代码】
#include <iostream>
using namespace std;
int dx[4] = { 1, 0, -1, 0 }; //方向控制
int dy[4] = { 0, 1, 0, -1 };
int box[4][4] = { 0 };
int cnt = 0;
void dfs(int Xstart, int Ystart, int length)
{
int nx, ny;
if (length == 16)
{
cnt++;
return ;
}
else
{
for (int i = 0; i < 4; i++) //搜索
{
nx = Xstart + dx[i]; //方向
ny = Ystart + dy[i];
//该格子不可放置 或越界 跳过该方向
if (box[nx][ny] == 1 || nx < 0 || nx > 3 || ny < 0 || ny > 3)
continue;
box[nx][ny] = 1; // 对已放置的格子进行标记
dfs(nx, ny, length+1);//错误:length++改为length+1
box[nx][ny] = 0; //清除标记
}
}
}
int main()
{
for (int a = 0; a < 4; a++)
for (int b = 0; b < 4; b++)
{
box[a][b] = 1;
dfs(a, b, 1);
box[a][b] = 0; //清除标记
}
cout << cnt << endl;
}
【运行结果】
2023/11/3 周五
数据结构实验9 二叉树
第一二题:
tree.h文件
typedef struct LBinaryTreeNode
{
ElemType data; /*数据域 */
struct LBinaryTreeNode *lchild;//左孩子
struct LBinaryTreeNode *rchild;//右孩子
}
LPBTreeNode;
//访问结点
void visit(LPBTreeNode *t)
{
printf("%c ",t->data);
}
//先序遍历算法
void preorder(LPBTreeNode *t)
{
if (t == NULL)
return ;
visit(t);
preorder(t->lchild);
preorder(t->rchild);
}
//中序遍历算法
void inorder(LPBTreeNode *t)
{
if (t == NULL)
return ;
inorder(t->lchild);
visit(t);
inorder(t->rchild);
}
//后序遍历算法
void postorder(LPBTreeNode *t)
{
if (t == NULL)
return ;
postorder(t->lchild);
postorder(t->rchild);
visit(t);
}
// 计算叶子结点数并打印
void caculateLeafNum(LPBTreeNode *root, int *leafNum)
{
if(root == NULL)
return ;
if(root->lchild == NULL && root->rchild == NULL)
{
(*leafNum)++;
visit(root);
}
caculateLeafNum(root->lchild, leafNum);
caculateLeafNum(root->rchild, leafNum);
}
//二叉树的打印
void PrintBiTree(LPBTreeNode *root, int n)
{
int i;
if(root == NULL)
return ;
PrintBiTree(root->rchild, n+1);
//访问根结点
for(i = 0; i <= n-1; i++)
printf(" ");
if(n >= 0)
{
printf("---");
printf("%c\n", root->data);
}
PrintBiTree(root->lchild, n+1);
}
/*从根开始递归创建二叉树 */
LPBTreeNode *createbintree(void)
{
LPBTreeNode *pbnode;
char ch;
scanf("%c", &ch);
if(ch == '#')
pbnode = NULL;
else
{
pbnode = (LPBTreeNode *) malloc(sizeof(LPBTreeNode));
if( pbnode == NULL )
{
printf("0ut of space!\n");
return pbnode;
}
pbnode->data = ch;
pbnode->lchild = createbintree(); //构造左子树
pbnode->rchild = createbintree(); //构造右子树
}
return pbnode;
}
.c文件
#include<stdio.h>
#include<malloc.h>
typedef char ElemType;
#include "tree.h"
int main()
{
int leafNum = 0;
LPBTreeNode *T;
printf("请输入扩展先序历序列:");
T=createbintree();
PrintBiTree(T, 0); //打印二叉树
printf("\n");
printf("\n先序遍历: \n");
preorder(T);
printf("\n中序遍历: \n");
inorder(T);
printf("\n后序遍历: \n");
postorder(T);
printf("\n\n");
caculateLeafNum(T, &leafNum);
printf("%d", leafNum);
}
【运行结果】
2023/11/4-5 周六到周日
蓝桥杯练习4 找朋友
【题目描述】
X,作为户外运动的忠实爱好者,总是不想呆在家里。现在,他想把死宅 Y 从家里拉出来。问从 X的家到 Y 的家的最短时间是多少。
为了简化问题,我们把地图抽象为 n*m 的矩阵,行编号从上到下为 1 到 n,列编号从左到右为 1 到 m。矩阵中 ’X’ 表示 X 所在的初始坐标,’Y’ 表示 Y 的位置 , ’#’ 表示当前位置不能走,’ * ’ 表示当前位置可以通行。X 每次只能向上下左右的相邻的 ’ * ’ 移动,每移动一次耗时1秒。
【输入样式】
多组输入。每组测试数据首先输入两个整数n,m(1<= n ,m<=15 )表示地图大小。接下来的 n 行,每行m个字符。保证输入数据合法。
【输出样式】
若X可以到达Y的家,输出最少时间,否则输出 -1。
【样例输入】
3 3
X#Y
***
#*#
3 3
X#Y
*#*
#*#
【样例输出】
4
-1
【代码】
#include <iostream>
using namespace std;
char box[10][10];
int mov[10][10];
int dx[4] = { 1, 0, -1, 0 };
int dy[4] = { 0, 1, 0, -1 };
int Min = 9999;
int a, b;
void dfs(int Xstart, int Ystart, int step)
{
int nx, ny;
if (step >= Min)
{
return ;
}
if (box[Xstart][Ystart] == 'Y')
{
if (step < Min)
{
Min = step;
}
return ;
}
else
{
for (int i = 0; i < 4; i++)
{
nx = Xstart + dx[i];
ny = Ystart + dy[i];
if (Xstart >= 0 && Xstart < a && Ystart >= 0 && Ystart < b
&& mov[nx][ny] == 0 && box[nx][ny] != '#')
{
mov[nx][ny] = 1;
dfs(nx, ny, step + 1);
mov[nx][ny] = 0;
}
}
}
}
int main()
{
int i, j;
int t = 2;
while (t--)
{
cin >> a >> b;
Min = 9999;
for (i = 0; i < a; i++)
{
for (j = 0; j < b; j++)
{
cin >> box[i][j];
}
}
dfs(0, 0, 0); //Xstart, Ystart应该为初始值
if (Min == 9999)
cout << "-1" << endl;
else
cout << Min << endl;
}
return 0;
}
【运行结果】