《深入浅出程序设计竞赛》读书笔记
笔记名称:《深入浅出程序设计竞赛》
目录
超声波/红外避障小车设计与实现....................................................................10
阅读书籍: 《深入浅出程序设计竞赛》
作者首先介绍了编程竞赛的基本概念和要点。竞赛题目往往涉及到数学、逻辑和算法等多个领域,其中算法又与数据结构密不可分。作者通过实例引导读者思考如何灵活运用数据结构解决问题,以简单而贴切的语言解释了竞赛的本质,同时在讨论算法时,强调了数据结构的重要性,使我对学习数据结构的动力得以提升。
第二章主要涵盖了基本算法,其中排序算法是其中的重要一环。排序算法在程序设计竞赛中应用广泛,而排序的本质则是对数据的组织。通过对不同排序算法的比较,读者能够更深刻地理解数据在排序过程中的变化,进而联系到数据结构的基本概念。在学习排序算法时,不能仅仅停留在算法本身,更需注意排序对数据结构的影响,建立排序算法与数据结构的联系。
书中对时间复杂度和空间复杂度的详细讲解使我深刻理解了算法效率的重要性。通过学习不同数据结构的实现和它们在不同场景下的性能表现,我能够更好地选择和设计合适的数据结构来解决特定问题。这对于编写高效的程序至关重要,尤其是在面对大规模数据时。
该方法的基本思想是:挖坑填数+分治法
2.分区,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
对挖坑填数进行总结
1.i =L; j = R; 将基准数(第一个,最后一个,中间一个或者随机一个都可以)挖出(临时存放于temp)形成第一个坑a[i]。
2.j--由后向前找比temp小的数,找到后挖出此数填前一个坑a[i]中,形成新的坑。
3.i++由前向后找比temp大的数,找到后也挖出此数填到前一个坑a[j]中,形成新的坑。
4.再重复执行2,3二步,直到i==j,将基准数填入a[i]中,所有坑填完。
在最差情况下(选择了最大、最小值作为基准数,则i右前向后遍历、j每次都由后向前遍历一次,复杂度O(n^2));如果每次都是取到当前处理序列的中值,则只需递归logn次,每次交换时i、j共遍历n次,复杂度为O(nlogn)。
//快速排序 voidquick_sort(ints[], intl, int r)
{
if(l < r) //执行分治的判断式,当l=r时,即说明不能再划分,不再递归 {
inti = l, j = r, x = s[l]; //i,j分别从数组的左,右开始向中间递进,X作为暂时储存器存放基准数,此处把第一个元素作为基准数while(i < j) //挖坑填数过程,当i==j时说明已全部遍历,停止循环 {
while(i < j && s[j] >= x) // 从右向左找第一个小于x的数 j--;
if(i < j) //当上述循环退出时,说明找到了小于基准数的元素,判断此时下标,若在i的右边,说明未遍历过,则填到[i]处s[i++] = s[j];
while(i < j && s[i] < x) // 从左向右找第一个大于等于x的数 i++;
if(i < j) //当上述循环退出时,说明找到了大于等于基准数的元素,判断此时下标,若在j的左边,说明未遍历过,则填到[j]处s[j--] = s[i];
}
s[i] = x; //当i==j时退出循环,此处填入中间数(基准数)quick_sort(s, l, i - 1); // 递归调用,对数组左右划分,直到相邻两元素比较交换,实现全部有序 注意:此处是先执行排序交换再递归的,而不是递归到底层再返回上来,函数没有return语句quick_sort(s, i + 1, r);
}
}
第三章:搜索算法
深度优先搜索与树结构的契合
搜索算法是程序设计竞赛中常见的解决问题的手段之一。深度优先搜索作为其中一种重要的搜索方式,与树结构的联系不可忽略。通过深入解析深度优先搜索的原理,可以清晰地看到树结构在搜索过程中的应用,这对于理解树形数据结构有着积极的促进作用。将搜索算法与树结构的关系进行深入剖析,提供了更直观的认识,使我得学习的深度有了质的提升。
a.贪心思想:
贪心就是遵循某种规律,不断贪心选取当前最优策略。
b.贪心证明:
· 与其它选择方案相比,该算法并不会得到更差的解 (归纳法)。
· 不存在其他的解决方案(反证法)。
动态规划是解决一类问题的重要方法,在程序设计竞赛中常见且应用广泛。动态规划的基本原理,着重强调状态转移的关键。这一点与图结构的概念有着密切联系,通过对状态转移的深入理解,才能够更好地理解图结构在动态规划中的应用。通过对动态规划状态转移的解释,揭示了动态规划与图结构的内在联系,拓展了解题思路的角度。
a.核心思想:
1.动态规划(DP):通过定义某种最优子状态,进行状态间转移达到最终解。
3.多种形式的DP:搜索的记忆化或利用递推关系的DP,或从状态转移考虑的DP。
状态定义和循环顺序都会影响复杂度。
b.优化细节 :
1.使用memset初始化
2.重复循环数组
3.dp仅bool是一种浪费
c.经典模型:
2.划分数类型: 就是n的m划分(第二类Stirling数,Bell数)
最长公共子序列(LCS)介绍: 一个序列即是X序列的子序列,也是Y序列的子序列,则该序列称为为X和Y的公共子序列。对于两个序列的公共子序列是不唯一的,因此,最长公共子序列顾名思义就是长度最长的公共子序列。
右下角开始,值为3时“←”,值为2时“↑”,值为1时“↖”,这样就找到了路径。
返回时,如果 b[i][j]为1就输出。于是得到{5,8,9,3}。
- #include <iostream>
- #include <algorithm>
- #include <string.h>
- using namespace std;
- const int N = 1010;
- char s1[N], s2[N];
- int c[N][N];
- int b[N][N] = {0};
- void print(int i, int j) {
- if (i == 0 || j == 0) return;
- if (b[i][j] == 1) {
- print(i - 1, j - 1);
- cout << s1[i];
- }
- else if (b[i][j] == 2) print(i - 1, j);
- else if (b[i][j] == 0) cout << '0';//!!!!!!!!!!!!!!修改
- else print(i, j - 1);
- }
- int main()
- {
- //最优子结构状态值初始化,也可以不用
- memset(c, 0, sizeof(c));
- //输入序列s1和s2的长度 cin >> len1 >> len2;
- //输入需要求最长公共子序列的序列s1和s2
- while (cin >> s1 >> s2 )
- {
- int len1 = strlen(s1);
- int len2 = strlen(s2);
- for (int i = 1; i <= len1; i++) {
- for (int j = 1; j <= len2; j++) {
- if (s1[i] == s2[j]) {
- c[i][j] = c[i - 1][j - 1] + 1;
- b[i][j] = 1;//“↖”
- }
- else if (c[i - 1][j] >= c[i][j - 1]) {
- c[i][j] = c[i - 1][j];
- b[i][j] = 2;
- }
- else {
- c[i][j] = c[i][j - 1];
- b[i][j] = 3;
- }
- }
- }
- cout<<c[len1][len2]<<'\n';//"最大公共子序列长度为:"
- //print(len1, len2);//cout << "最大公共子序列为:";
- cout << '\n';
- }
- return 0;
- }
最短路径算法与图的遍历
图论在程序设计竞赛中占有重要地位,而其中最短路径算法是常见而关键的一环。通过对最短路径算法的分析,可以清晰地看到图的遍历在算法中的地位,这直接关系到了图结构的性质。将最短路径算法与图的遍历紧密结合,才能搭建解决图论问题的桥梁。最短路径算法与图的遍历进行深度剖析,使学习的过程更加具有条理性。
通过学习动态规划算法,我深入理解了数据结构的原理和算法的设计。在实际问题中,动态规划的状态转移过程往往依赖于合适的数据结构。这种融合不仅提高了算法的效率,也展现了数据结构在算法设计中的重要性。这些知识不仅为我提供了解决实际问题的工具,也培养了我在面对复杂编程挑战时的自信心。数据结构是计算机科学中的核心概念,对于成为一名优秀的程序员或算法工程师至关重要。在今后的学习和实践中,我将持续深化对数据结构的理解,并不断提升自己在算法设计和实现方面的能力。
[1]汪楚奇.深入浅出程序设计竞赛(基础篇)[M].高等教育出版社,2020,(10):64.
自学微信小程序开发,掌握了部分HTML、CSS和JSON
小案例展示:
蓝牙控制的超声波/红外避障小车设计与实现
学习pid算法,思考如何用作在电机转动上,使其完成闭环控制(使小车行驶更稳定,更直),通过算法写入控制小车完美避障。