第四周代码(二叉树一 + 搜索算法)

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;
}

【运行结果】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值