0.2022年10月,A卷,;
题目一,
给定一个数组,array = {2,3,38,5,4}, 一个数字n,求数组中是否存在一个序列使得之和等于n,例如n=9,如果存在输出True, 否则输出False,用递归的方法。
//这个问题可以有多个变体:
//1.子集和问题,有回溯法,这个参考的算法比较简洁:https://blog.csdn.net/qq_62899367/article/details/122383351?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522169893884816800180655506%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=169893884816800180655506&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-122383351-null-null.142^v96^control&utm_term=%E5%AD%90%E9%9B%86%E5%92%8C%E9%97%AE%E9%A2%98&spm=1018.2226.3001.4187
//如果单纯只是判断,是否存在这样的素组,可以使用以下简洁的方法;
//对于有n个元素的数组,对于是否存在某子集使其和等于某数;
//这个问题可以简化,对每个元素来说,是否应该加入到结果子集中;
int sum(int n, int m) //含有n个元素的集合,是否存在子集使其和为m;
{
if (sum[n] == m)
flag = true;
else if(n == 1)
return;
else
{
//对于任意元素都是,是否要加入到子集中;
sum(n - 1, m - sum[n]); //取了元素n的情况;
sum(n - 1, m); //没有取元素n的情况;
}
}
题目二,
要求在某个节点上建一个健身房,使所有节点到健身房的路程最小;约定相邻节点间的距离为1;
代码我直接复制其他人的,参考:【精选】dijkstra算法详解—简单易懂-CSDN博客
如果有其他更简洁的写法,欢迎提出来。
void dijkstra(){
//源点为源点start。
int minn;//记录每趟最短路径中最小的路径值。
int pos;//记录得到的minn所对应的下标。
init();//调用初始化函数。
visited[start]=true;
for(int i=1;i<=n;i++){
//将n个顶点依次加入判断。
minn=inf;
for(int j=1;j<=n;j++){
if(!visited[j]&&dis[j]<minn){
minn=dis[j];
pos=j;
}
}
//经过这趟for循环后我们找到的就是我们想要的点,可以确定这点到源点的最终最短距离了。
visited[pos]=true;//我们将此点并入已知集合。
//接下来就是更新dis数组了,也就是当前最短距离,这都是针对还没有并入已知集合的点。
for(int j=1;j<=n;j++){
if(!visited[j]&&dis[j]>dis[pos]+graph[pos][j])
dis[j]=dis[pos]+graph[pos][j];
}
}
//退出循环后,所有的点都已并入已知集合中,得到的dis数组也就是最终最短距离了。
cout<<dis[goal]<<endl;//输出目标点到源点的最短路径长度。
}
dijkstra求最短路径
//上次考的是dijkstra;
这一次考的是
5个城市节点,8个边,每个边的权值为高速公路的造价;
example, 2, 3, 50; //50为高速公路造价;
五个城市间,造4条高速公路,使总造价最低;
1.2022年10月,B卷,第一题;
1.1.题目:二叉树的先序和中序,求后序;
例如:二叉树的先序遍历为abdec, 中序遍历为dbcae; 求后序遍历;
1.2.解题思路:
考虑递归;先回顾下正常的后序遍历算法;
(自我总结:叶子节点,作为一个子树时,该叶子节点就是该子树的根节点,三种遍历算法就是递归的以一定的顺序遍历根节点;先序遍历是:根节点-左子树的先序遍历-右子树先序遍历;后序遍历是:左子树的后序遍历-右子树的后序遍历-根节点)
/* 此题作为后序遍历算法的变种,一定是这种思路 */
void post()
{
post(); /* left tree */
post(); /* right tree */
printf("root");
}
1.3.其中一种解法(参考:
#include <stdio.h>
char *preorder = "abdec";
char *inorder = "dbeac";
//very interesting, 每一遍理解都不一样,这里可以理解为,一直在寻找自由一个值的树,然后把它打印出来;
//这一个值可以理解为左子树=右子树=根;
//这个算法的关键是理解inorder中某个子树的根在preorder中的下标;
//i - start的含义:此次遍历,左子树中元素的数量。那么右子树的根在preorder中的下标必然为,root + 1 + (i - stat) = 根的下一个位置+左子树的偏移量;
/* 参数root是先序遍历序列中根的位置下标, start, end是树在中序遍历序列中的起始位置
*
*/
void post(int root, int start, int end)
{
int i;
for (i = start; i <= end; i++) {
if (inorder[i] == preorder[root]) {
post(root + 1, start, i - 1); /* 后序遍历左子树 */
post(root + (i - start) + 1, i + 1, end); /* 后序遍历右子树 */
printf("%c", preorder[root]);
}
}
}
)
2.2022年10月,B卷,第二题(具体题目记不清了,类似下题);
一班有m个男生,n个女生(m!=n),举办舞会,男女生分别编号坐在舞池两旁,每曲开始时,依次从男生和女生中各出一人配对跳舞,没有配对成功的等待下一曲,设计程序模拟舞伴配对过程。
2.1解题思路,按照队列处理;
1 #include <stdio.h>
2
3 #define MAN 13
4 #define WOMAN 14
5 char *man_string = "ABCDEFGHIJKLM";
6 char *woman_string = "abcdefghijklmn";
7
8 typedef struct {
9 char *man;
10 int front;
11 } man_queue;
12
13 typedef struct {
14 char *woman;
15 int front;
16 } woman_queue;
17
18 void test(void)
19 {
20 man_queue dance_man;
21 woman_queue dance_woman;
22 dance_man.man = man_string;
23 dance_woman.woman = woman_string;
24 dance_man.front = 0;
25 dance_woman.front = 0;
26
27 while (dance_man.front < MAN) {
28 printf("man %c, woman %c\n",
29 dance_man.man[dance_man.front],
30 dance_woman.woman[dance_woman.front]);
31
32
33 if (dance_man.front == MAN - 1) {
34 printf("dance is over!, wait next\n");
35 sleep(5);
36 }
37
38 dance_man.front = (dance_man.front + 1) % MAN;
39 dance_woman.front = (dance_woman.front + 1) % WOMAN;
40 }
41 }
41,1 25%
2023年11月5日,数据结构试卷
第一题:有1,2, 3,.... n个人,依次报数,报数到m时出列,直到所有人都出列;
//这个考试队列的引用;
第二题,
5个城市节点,8个边,每个边的权值为高速公路的造价;
example, 2, 3, 50; //50为高速公路造价;
五个城市间,造4条高速公路,使总造价最低;
//这次考试Floyd算法,求任意两点间的最短路径;参考:七、最短路径——弗洛伊德(Floyd)算法_floyd算法求最短路径问题_瘦弱的皮卡丘的博客-CSDN博客
void ShortestPath_Floyd(MGraph G, vector<vector<int>>& P, vector<vector<int>>& D)
{
for (int i = 0; i < G.numVertexte; ++i)
{
for (int j = 0; j < G.numVertexte; ++j)
{
D[i][j] = G.arc[i][j];//用G的邻接矩阵初始化D
P[i][j] = j;
}
for (int i = 0; i < G.numVertexte; ++i)
{
for (int j = 0; j < G.numVertexte; ++j)
{
for (int w = 0; w < G.numVertexte; ++w)
{
if (D[j][w] > D[j][i] + D[i][w])//如果经过下标为i的顶点路径比原两点间路径更短
{
D[j][w] = D[j][i] + D[i][w];//更新D的值
P[j][w] = P[j][i];//更新P的值
}
}
}
}
}
}