首页 | 教学环境 | 课程体系 | 关于我们 | 常见问题(FAQ)

算法之美
少儿编程教学

专为8-15岁少儿设计的20集C++算法短视频课程, 每集10分钟,融合趣味性与计算思维培养, 让孩子在编程中感受数学之美与算法智慧。

20集少儿编程视频课程
线下每次课2小时
C++编程

二分查找

50次到7次的效率跃迁

素数判断

千倍优化的数学智慧

排序算法

冒泡与选择的策略对比

递归精髓

汉诺塔的分治思想

课程设计哲学

趣味性驱动

通过游戏化问题和生动类比,激发孩子的学习兴趣,让算法学习充满乐趣。

计算思维培养

从具体问题抽象数学模型,培养分治、递归、贪心等核心计算思维能力。

竞争优势

掌握算法优化思维,培养同龄人中突出的问题解决能力和编程素养。

课程特色

✨ 视觉冲击设计

  • • 从50次随机猜测到7次精准定位的震撼对比
  • • 素数判断从999,999次到1,000次的千倍优化
  • • 斐波那契数列从指数灾难到对数优化的2亿倍提升

🎯 生活应用关联

  • • 二分查找:网购价格筛选、字典查词
  • • 排序算法:手机联系人排序、成绩表可视化
  • • 递归思想:文件目录遍历、表达式求值

教学目标

通过20集精心设计的算法课程,让孩子理解算法的本质不是枯燥的代码,而是将"不可能完成的任务"转化为"瞬间响应"的智慧结晶。每集课程都包含完整题目描述、解题思路、C++代码实现、演变题型和生活应用五大模块,确保学习的系统性和深度。

01

猜数字游戏与二分查找

从50次随机猜测到7次精准定位的思维跃迁

题目描述

小明和小红玩猜数字游戏。小红心里想一个1到100之间的整数,小明每次猜一个数字,小红会告诉他是"猜大了"、"猜小了"还是"猜对了"。请帮小明设计一个最优策略,用最少的次数猜出这个数字。

震撼数据对比

数据规模100: 线性查找 50次 vs 二分查找 7次
数据规模1亿: 线性查找 5千万次 vs 二分查找 27次

核心代码

int binarySearch(int n, int target) {
    int left = 1, right = n;
    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (mid == target) return mid;
        else if (mid < target) left = mid + 1;
        else right = mid - 1;
    }
    return -1;
}

生动类比:电话簿查号

想象一本1000页的电话簿,寻找"张三"的号码。聪明的做法是直接翻到中间第500页,看到姓氏首字母为"M",由于"张"在"M"之后,立即排除前500页,将搜索范围压缩一半;再翻到第750页,继续比较、排除、压缩……每次都将搜索范围减半,最多10次必中。

常见代码错误

  • 中间值溢出: (left+right)/2 应改为 left+(right-left)/2
  • 边界更新死循环: right=mid 应改为 right=mid-1
  • 终止条件混淆: 确保单元素区间被正确检查

生活应用

  • 网购价格筛选:电商平台的价格区间底层实现
  • 字典查词:纸质字典的查阅过程本身就是二分查找
  • 数据库索引:B+树等数据结构的搜索基础
02

素数判断与试除法优化

从暴力枚举到数学优化的思维成长

优化层级对比

基础试除法

验证范围:2 到 n-1

100万素数:999,999次验证

√n优化

验证范围:2 到 √n

100万素数:1,000次验证 (1000倍提升)

6k±1优化

仅验证6k±1形式到√n

100万素数:333次验证 (再降67%)

6k±1优化代码

bool isPrime(long long n) {
    if (n <= 1) return false;
    if (n <= 3) return true;
    if (n % 2 == 0 || n % 3 == 0) 
        return false;

    for (long long i = 5; i * i <= n; i += 6) {
        if (n % i == 0 || n % (i + 2) == 0) 
            return false;
    }
    return true;
}

生动类比:"社交孤独者"检测

素数就像社交圈中的孤独者,只能被1和自己整除。判断时只需问到"朋友圈半径"√n——若有"远方的朋友"(大因子),必有"近处的朋友"(对应小因子)作为中介。

生活应用

  • RSA加密:随机选择两个大素数p和q,计算n=pq
  • 哈希表设计:选择素数作为哈希表容量,减少冲突
  • 信息安全:大素数分解的困难性是现代密码学基础

常见错误

  • 特殊情况遗漏:未处理n=1(非素数)、n=2(唯一偶素数)
  • 循环边界错误:应用i*i<=n而非i<=sqrt(n)
  • 6k±1优化结构错误:未先排除偶数,或循环内验证偶数
03

冒泡排序与交换思想

相邻比较、逐步有序的可视化过程

题目描述

给定一个包含n个整数的数组,请使用冒泡排序算法将其按升序排列。要求实现提前终止优化:如果某一轮没有发生任何交换,说明数组已经有序,可以提前结束排序。

核心思想

  • • 每轮将当前最大元素"沉"到正确位置
  • • 通过相邻交换逐步有序
  • • 提前终止优化:无交换则已有序

冒泡排序代码

void bubbleSort(int arr[], int n) {
    for (int i = 0; i < n - 1; i++) {
        bool swapped = false;
        for (int j = 0; j < n - 1 - i; j++) {
            if (arr[j] > arr[j + 1]) {
                swap(arr[j], arr[j + 1]);
                swapped = true;
            }
        }
        if (!swapped) break; // 提前终止
    }
}

生动类比:气泡上升

轻的气泡(小值)通过相邻交换逐步"浮"到数组前端,每轮最大元素"沉"到正确位置。就像排队调身高:相邻两人比较,高的往后站,一轮下来最高者到队尾,重复直至有序。

复杂度分析

  • 最好情况:O(n) - 已有序,只需一轮
  • 最坏情况:O(n²) - 逆序数组
  • 空间复杂度:O(1) - 原地排序
  • 稳定性:稳定排序

常见错误

  • 内层循环边界错误:j < n-1未随i递减
  • 交换标志位遗漏:无swapped标志,失去提前终止
  • 比较方向错误:升序用>,降序用<
04

斐波那契数列与递推思想

从指数灾难到对数优化的2亿倍效率提升

算法复杂度对比

纯递归

时间:O(2ⁿ)

空间:O(n)

F(50): ~10¹⁰ 操作

滚动数组

时间:O(n)

空间:O(1)

F(50): 50 操作

矩阵快速幂

时间:O(log n)

空间:O(1)

F(50): ~240 操作

滚动数组实现

long long fib(int n) {
    if (n <= 1) return n;
    long long a = 0, b = 1, c;
    for (int i = 2; i <= n; i++) {
        c = (a + b) % MOD;
        a = b;
        b = c;
    }
    return b;
}

生动类比

兔子家族:每对成熟兔子每月生一对新兔子,新兔子次月成熟。这就是斐波那契数列的经典来源。

楼梯问题:每次走1步或2步,到第n层的方法数满足相同递推关系。

生活应用

  • 植物叶片排列:相邻叶片角度≈137.5°=360°/φ²
  • 金融复利增长:斐波那契的指数增长特性
  • 兔子繁殖模型:每对成熟兔子每月生一对新兔子

常见错误

  • 递归无记忆化:指数级重复计算
  • 数组越界:未处理n=0, n=1边界
  • 取模位置错误:先加后取模导致溢出
05

汉诺塔问题与递归精髓

将大问题分解为相同结构的小问题

题目描述

有三根柱子A、B、C,A柱上有n个盘子,盘子大小不一,大盘在下小盘在上。要求将所有盘子从A柱移动到C柱,规则:每次只能移动一个盘子,大盘不能放在小盘上面,可以使用B柱作为辅助。

趣味数据

  • • 3个盘子:7步
  • • 4个盘子:15步
  • • 64个盘子:约5800亿年(远超宇宙年龄!)

递归代码

void hanoi(int n, char from, char aux, char to) {
    if (n == 1) {
        cout << from << " -> " << to << endl;
        return;
    }
    // 1. 将n-1个从from移到aux
    hanoi(n-1, from, to, aux);
    // 2. 移动最底下的盘子
    cout << from << " -> " << to << endl;
    // 3. 将n-1个从aux移到to
    hanoi(n-1, aux, from, to);
}

生动类比:和尚搬盘子

大和尚让小和尚先搬上面的n-1个到辅助柱,自己搬最底下的,再让小和尚把n-1个搬到目标柱——层层委托,直到最小和尚只搬1个。就像电影《盗梦空间》:梦中梦,层层深入(递)再逐层返回(归)。

递归三要素

  • 终止条件:n==1时直接移动
  • 递归调用:分解为n-1的子问题
  • 结果合并:三步策略组合解

常见错误

  • 参数顺序错误:源柱、辅助柱、目标柱混淆
  • 终止条件缺失:n=0或n<0未处理
  • 打印位置错误:移动语句放在递归调用之前或之后
06

水仙花数与数字分解

数字的"自幂"美学与位运算

题目描述

水仙花数(Narcissistic number)是指一个n位数,其各位数字的n次幂之和等于它本身。例如:153 = 1³ + 5³ + 3³ = 1 + 125 + 27 = 153。

三位数水仙花数

153 = 1³ + 5³ + 3³
370 = 3³ + 7³ + 0³
371 = 3³ + 7³ + 1³
407 = 4³ + 0³ + 7³

数字分解代码

bool isNarcissistic(int n, int digits) {
    int original = n, sum = 0;
    while (n > 0) {
        int digit = n % 10;  // 取个位
        sum += pow(digit, digits);
        n /= 10;  // 右移一位
    }
    return sum == original;
}

生动类比:数字的"自恋"

各位数字的n次幂之和恰好等于自己,如同自恋者只关注自己的各个"维度"。这种数学与文学的交融,让枯燥的数字变得有趣。

演变题型

  • 四叶玫瑰数(4次幂):1634, 8208, 9474
  • 完全数判断:真因子之和等于自身
  • 数字黑洞(6174猜想):卡普雷卡常数

常见错误

  • 分解顺序错误:从低位(个位)开始
  • 幂次计算溢出:未考虑大数用long long
  • 原数修改丢失:提前保存original = n
07

回文数判断与双指针

对称美学的算法实现

题目描述

回文数是指正读和反读都相同的数字或字符串。例如:121、"level"、"上海自来水来自海上"。给定一个整数或字符串,判断它是否为回文。

双指针思想

left从0开始,right从末尾开始,向中间移动,O(n)时间O(1)空间的最优解。

双指针代码

bool isPalindrome(string s) {
    int left = 0, right = s.length() - 1;
    while (left < right) {
        while (left < right && !isalnum(s[left])) left++;
        while (left < right && !isalnum(s[right])) right--;
        if (tolower(s[left]) != tolower(s[right])) 
            return false;
        left++; right--;
    }
    return true;
}

生动类比:照镜子

左右对称,两端字符一一对应,如同镜像。双指针技术不仅用于回文判断,还是滑动窗口、快慢指针等高级技巧的基础。

演变题型

  • 最长回文子串:中心扩展法
  • 回文链表判断:快慢指针找中点
  • 最少插入次数构成回文:动态规划

常见错误

  • 指针交叉条件错误:用left < right
  • 大小写未统一:tolower统一后再比较
  • 非字母数字未过滤:isalnum过滤
08

最大公约数与欧几里得算法

2300年前古希腊算法的现代生命力

题目描述

给定两个正整数a和b,求它们的最大公约数(GCD)和最小公倍数(LCM)。欧几里得算法:gcd(a, b) = gcd(b, a mod b),每次将问题规模指数级缩小。

核心公式

GCD: gcd(a, b) = gcd(b, a % b)
LCM: lcm(a, b) = a * b / gcd(a, b)
注意:先除后乘防溢出!

迭代版代码

int gcd(int a, int b) {
    while (b != 0) {
        int temp = a % b;
        a = b;
        b = temp;
    }
    return a;
}

long long lcm(int a, int b) {
    return (long long)a / gcd(a, b) * b;
}

生动类比:分土地

大长方形中不断切出最大正方形,剩余小长方形继续切,直到正好切完,最后正方形的边长就是GCD。这是"辗转相除"的直观理解。

演变题型

  • 扩展欧几里得:求解ax + by = gcd(a,b)
  • 多个数的GCD/LCM:迭代应用二元GCD
  • 模逆元计算:用于RSA解密

常见错误

  • 取模对象错误:确保a % b,大数对小数取模
  • 终止条件错误:b == 0时返回a
  • lcm溢出:先除后乘防溢出
09

选择排序与不稳定排序

每轮选最小的直观策略

题目描述

给定一个包含n个整数的数组,请使用选择排序算法将其按升序排列。选择排序的核心思想:每轮从未排序区选出最小元素,放到已排序区的末尾。

特点

  • • 交换次数最少(最多n-1次)
  • • 适合写操作代价高的场景
  • • 不稳定排序

选择排序代码

void selectionSort(int arr[], int n) {
    for (int i = 0; i < n - 1; i++) {
        int minIdx = i;
        for (int j = i + 1; j < n; j++) {
            if (arr[j] < arr[minIdx])
                minIdx = j;
        }
        if (minIdx != i)
            swap(arr[i], arr[minIdx]);
    }
}

生动类比:选秀比赛

每轮从所有选手中选出当前最强,放到已晋级区,而非相邻比较逐步调整。理解算法多样性与trade-off——没有"最好"的算法,只有"最适合"的算法。

演变题型

  • 找第K小元素:执行K轮选择
  • 双向选择排序:每轮同时找最大最小
  • 堆排序:选择排序的堆优化

常见错误

  • 最小值索引初始化错误:minIdx = i
  • 交换条件遗漏:if(minIdx != i)
  • 稳定性破坏未意识到:相等元素相对顺序改变
10

插入排序与有序插入

抓牌理牌的自然排序过程

题目描述

给定一个包含n个整数的数组,请使用插入排序算法将其按升序排列。插入排序的核心思想:将数组分为已排序区和未排序区,每次从未排序区取一个元素,插入到已排序区的正确位置。

特点

  • • 最好情况O(n)——数据已有序时仅需n-1次比较
  • • 增量式构建的算法思维
  • • 稳定排序

插入排序代码

void insertionSort(int arr[], int n) {
    for (int i = 1; i < n; i++) {
        int key = arr[i];
        int j = i - 1;
        while (j >= 0 && arr[j] > key) {
            arr[j + 1] = arr[j];
            j--;
        }
        arr[j + 1] = key;
    }
}

生动类比:扑克牌理牌

每张新牌插入到已排序区的正确位置,从后向前比较,找到位置后移元素腾出空间。实际系统中,小数组或近乎有序时插入排序优于快速排序。

演变题型

  • 希尔排序:插入排序的步长优化
  • 链表插入排序:避免元素后移
  • 计算逆序对数量:归并排序或树状数组

常见错误

  • 插入位置查找错误:从后向前遍历
  • 边界元素丢失:key = arr[i]保存
  • 循环终止条件错误:j >= 0
11

猴子吃桃与逆推思维

从结果倒推开点的逆向思维魅力

题目描述

一只猴子摘了一堆桃子,第一天吃了一半又多一个,第二天吃了剩下的一半又多一个,以此类推。到第10天早上想再吃时,只剩下1个桃子了。问:最初摘了多少个桃子?

逆推公式

设第n天剩1个,则第n-1天剩:(day[n] + 1) × 2
逆推10天得到初始桃子数

逆推代码

long long calculatePeaches(int n, int m) {
    long long day = m;  // 第n天剩m个
    for (int i = n - 1; i >= 1; i--) {
        day = (day + 1) * 2;  // 逆推
    }
    return day;  // 1534
}

生动类比:侦探破案

从现场痕迹倒推案发过程,而非从案发开始正向模拟。正向模拟需要枚举尝试,逆推公式直接计算,O(n)确定解。

演变题型

  • 酒壶问题:倒来倒去的逆推
  • 斐波那契的逆推:已知F(n)求n
  • 迷宫从终点找起点:双向BFS

常见错误

  • 逆推公式错误:先加1再乘2:(day + 1) * 2
  • 循环方向错误:for(i=n-1; i>=1; i--)
  • 初始条件错误:第10天剩1个,非吃完
12

百钱百鸡与穷举优化

中国古代数学问题的算法求解

题目描述

公鸡5钱、母鸡3钱、小鸡1钱3只,百钱买百鸡,求各多少只?理解"缩小搜索空间"的优化艺术——从O(n³)到O(n²)的提升。

优化效果

三重循环:101³ = 1,030,301 次
优化后:约 21 × 34 = 714 次
效率提升约1442倍!

优化代码

void buyChicken() {
    for (int x = 0; x <= 20; x++)  // 公鸡最多20只
        for (int y = 0; y <= 33; y++) {  // 母鸡最多33只
            int z = 100 - x - y;  // 小鸡
            if (z % 3 == 0 && 5*x + 3*y + z/3 == 100)
                printf("公鸡%d,母鸡%d,小鸡%d\n", x, y, z);
        }
}

生动类比:购物预算

在总钱数和总数限制下凑单,利用约束减少尝试组合。公鸡最多20只(5×20=100),母鸡最多33只(3×33=99),小鸡数量由总数约束确定。

演变题型

  • 五家共井:不定方程组
  • 鸡兔同笼:二元一次方程
  • 0-1背包穷举:约束优化

常见错误

  • 整数除法错误:z % 3 == 0前置判断
  • 循环边界错误:未利用总数约束减少上限
  • 解的重复计数:注意对称性去重
13

约瑟夫环与数学递推

从模拟到公式的高效性

题目描述

n个人围成圈,从第k个开始报数,每数到m者淘汰,求最后幸存者。理解数学公式替代模拟的高效性——从O(n²)链表模拟到O(n)递推公式。

递推公式

f(1) = 0
f(n) = (f(n-1) + m) % n
结果+1转换为1-based编号

递推代码

int josephus(int n, int m) {
    int res = 0;  // f(1) = 0
    for (int i = 2; i <= n; i++)
        res = (res + m) % i;
    return res + 1;  // 1-based
}

生动类比:围成圈报数淘汰

最后幸存者的位置,通过递推从2人逐步推导到n人。链表模拟每轮删除操作O(n),总O(n²);数学递推O(n)时间,O(1)空间。

演变题型

  • 双向约瑟夫环:顺时针逆时针交替
  • 步长变化:m随轮次变化
  • 最后两个幸存者:求倒数第二

常见错误

  • 初始条件错误:f(1)=0还是f(1)=1混淆
  • 取模对象错误:递推中是%i(当前人数)
  • 结果偏移错误:明确0-based/1-based
14

杨辉三角与二维递推

组合数学的视觉美感

题目描述

打印杨辉三角的前n行。杨辉三角的特点是:每行两端都是1,每个内部数等于上方两数之和。与二项式系数、组合数深度关联。

递推关系

C(n,k) = C(n-1,k-1) + C(n-1,k)
边界:C(n,0) = C(n,n) = 1

杨辉三角代码

void yanghui(int n) {
    int a[100][100] = {0};
    for (int i = 0; i < n; i++) {
        a[i][0] = a[i][i] = 1;  // 边界
        for (int j = 1; j < i; j++)
            a[i][j] = a[i-1][j-1] + a[i-1][j];
    }
}

生动类比:金字塔建造

每个砖块支撑上方两个砖块,底层稳固则整体稳固。掌握组合数的O(n²)预计算方法,理解杨辉三角与二项式定理的关系。

演变题型

  • 只打印第n行:空间优化到O(n)
  • 路径计数问题:网格从左上到右下
  • 卡特兰数:C(2n,n)/(n+1)

常见错误

  • 数组越界:j < i,每行i+1个元素
  • 边界条件遗漏:设置每行首尾为1
  • 输出格式错误:控制每行前的空格
15

排队接水与贪心算法

"短者优先"的直觉最优策略

题目描述

有n个人排队接水,第i个人接水需要t[i]分钟。如何安排排队顺序,使得所有人的等待时间之和最小?

贪心策略

按接水时间升序排序,依次接水。
总等待时间 = Σ(n-i)×t[i]

贪心代码

int totalWait(vector& t) {
    sort(t.begin(), t.end());  // 升序
    int sum = 0, n = t.size();
    for (int i = 0; i < n; i++)
        sum += t[i] * (n - i);  // 第i人影响后面n-i人
    return sum;
}

生动类比:超市结账

让买得少的人先结,减少后面人的等待,总等待时间最小。理解贪心算法的正确性证明——本题中按时间升序排列可证明为全局最优。

演变题型

  • 区间调度问题:按结束时间最早选择
  • 活动安排问题:最多兼容活动
  • 最小延迟调度:带截止时间的任务

常见错误

  • 排序关键字错误:按服务时间升序
  • 等待时间计算错误:第i人影响后面n-i人
  • 平均时间计算错误:除以人数位置
16

火车调度与栈的应用

栈"后进先出"的实际调度应用

题目描述

火车站有一个调度栈,火车按1,2,3,...,n的顺序进站。给定一个出栈序列,判断该序列是否可能。

核心思想

模拟过程:按入栈顺序,能出则出,不能则入。
最终判断是否能得到目标序列。

栈模拟代码

bool isValidPop(vector push, vector pop) {
    stack s;
    int j = 0;
    for (int i = 0; i < push.size(); i++) {
        s.push(push[i]);
        while (!s.empty() && s.top() == pop[j]) {
            s.pop();
            j++;
        }
    }
    return s.empty();
}

生动类比:火车站的调度轨道

后进的车先出,符合栈的LIFO特性。穷举所有序列是卡特兰数级别,指数增长;栈模拟O(n)判断可行性。

演变题型

  • 最小栈:支持O(1)获取最小值
  • 表达式求值:中缀转后缀
  • 括号匹配与嵌套深度:验证合法性

常见错误

  • 栈空判断遗漏:pop前检查
  • 指针移动错误:明确push/pop顺序
  • 终止条件错误:完整模拟后判断
17

四皇后问题与回溯算法

"尝试-失败-回退-再尝试"的问题解决智慧

题目描述

在4×4的棋盘上放置4个皇后,使得任意两个皇后都不在同一行、同一列、同一对角线上。求所有可行的摆放方案。

核心思想

逐行放置,检查列与对角线冲突。
冲突则尝试下一列,所有列都冲突则回溯。

回溯代码

void backtrack(int row, int board[]) {
    if (row == 4) { 
        printSolution(); 
        return; 
    }
    for (int col = 0; col < 4; col++) {
        if (isSafe(row, col, board)) {
            board[row] = col;
            backtrack(row + 1, board);
            // 回溯:无需显式恢复
        }
    }
}

生动类比:安排座位

尝试每个位置,冲突则换,都不行则回退上一层重新尝试。纯穷举4⁴=256种,回溯剪枝实际搜索量大幅减少。

演变题型

  • N皇后问题:位运算优化
  • 数独求解:约束传播+回溯
  • 迷宫求解(DFS回溯):二维网格搜索

常见错误

  • 状态未恢复:回溯时清除当前选择
  • 对角线判断错误:abs(i-row) == abs(board[i]-col)
  • 终止条件位置错误:收集解后继续或返回
18

迷宫问题与深度优先搜索

"一条路走到黑,不通则回"的探索策略

题目描述

给定一个n×m的迷宫,0表示通路,1表示墙壁。从起点(0,0)出发,求到达终点(n-1,m-1)的一条路径(如果存在)。

核心思想

四个方向尝试,标记访问,递归深入。
到达终点或无路可走时回溯。

DFS代码

bool dfs(int x, int y) {
    if (x == targetX && y == targetY) return true;
    vis[x][y] = true;
    for (int i = 0; i < 4; i++) {
        int nx = x + dx[i], ny = y + dy[i];
        if (valid(nx, ny) && !vis[nx][ny])
            if (dfs(nx, ny)) return true;
    }
    return false;
}

生动类比:走迷宫的"右手规则"

沿墙走,标记已访问,避免绕圈。随机游走可能无限循环或遗漏路径;DFS适合路径存在性判断,BFS适合最短路径。

演变题型

  • 岛屿数量:连通块计数
  • 单词搜索:二维网格找单词
  • 黄金矿工:带权值的路径搜索

常见错误

  • 访问标记未设置:进入时立即标记
  • 边界检查遗漏:valid函数统一检查
  • 回溯时标记未清除:根据需求处理
19

日期计算与逻辑处理

编程处理日常问题的实用性

题目描述

给定一个日期(年、月、日),计算:该日期是星期几、该日期是当年的第几天、该日期所在月份有多少天。

闰年判断

四年一闰,百年不闰,四百年再闰
(year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)

闰年判断代码

bool isLeap(int year) {
    return (year % 4 == 0 && year % 100 != 0) 
           || (year % 400 == 0);
}

int daysInMonth(int year, int month) {
    if (month == 2) 
        return isLeap(year) ? 29 : 28;
    if (month == 1 || month == 3 || ...)
        return 31;
    return 30;
}

生动类比:日历翻页

考虑大小月、闰年的特殊处理,逻辑完备才能正确。日期计算是检验代码严谨性的经典场景。

演变题型

  • 计算两个日期间的天数:逐日累加或公式
  • 计算星期几:蔡勒公式/基姆拉尔森
  • 日程冲突检测:区间比较

常见错误

  • 闰年判断顺序错误:(year%400==0)优先
  • 月份天数数组越界:数组大小13
  • 日期合法性验证遗漏:如4月31日
20

贪吃蛇游戏与综合应用

多算法融合的综合项目成果展示

综合项目特色

作为20集课程的集大成者,贪吃蛇游戏融合了队列/链表维护蛇身、碰撞检测、随机食物生成、实时输入处理等多项技术,是前19集知识的综合应用。

核心算法融合

  • 数据结构:队列/链表维护蛇身
  • 碰撞检测:边界检查与自身遍历
  • 随机生成:食物位置的冲突检测
  • 实时处理:键盘输入的方向控制

蛇身实现核心代码

struct Snake {
    deque> body;
    int dir;

    void move(int newDir) {
        // 禁止180度转向
        if (abs(newDir - dir) != 1 || newDir + dir == 3)
            dir = newDir;

        pair head = body.front();
        int nx = head.first + dx[dir];
        int ny = head.second + dy[dir];

        body.push_front({nx, ny});  // 新头
        body.pop_back();             // 去尾
    }
};

模块化设计与系统集成

培养模块化设计与系统集成能力,建立实时系统的状态管理意识——游戏循环、输入响应、画面更新的协调。这是从学习算法到创造应用的跨越。

生活应用

  • 路径规划导航:实时最优路径计算
  • 机器人运动控制:避障与目标追踪
  • 游戏AI:NPC寻路、策略决策
  • 实时系统:状态管理与用户交互

常见错误

  • 蛇身碰撞检测遗漏:未检查除头外的身体
  • 方向控制冲突:允许180度直接反向
  • 食物生成死循环:蛇占满屏幕时未处理
  • 边界条件处理:撞墙检测不完整

20集课程知识图谱

基础算法

  • • 二分查找
  • • 素数判断
  • • 排序算法
  • • 递归思想

数据结构

  • • 栈的应用
  • • 队列实现
  • • 链表基础
  • • 数组操作

数学思维

  • • 斐波那契数列
  • • 最大公约数
  • • 组合数学
  • • 数论基础

高级算法

  • • 贪心算法
  • • 回溯算法
  • • DFS搜索
  • • 动态规划

课程特色总结

系统性学习

从基础到高级,循序渐进,构建完整的算法知识体系

趣味性驱动

通过游戏化问题和生动类比,让学习充满乐趣

实用性导向

结合生活应用,理解算法的实际价值和意义