欢迎光临
我们一直在努力

蓝桥杯python备赛笔记之(十)数论基础 & 日期问题

前言 整篇笔记共分为十章,都是博主在准备25年蓝桥杯时所写,听的网课是这个,讲的非常好,很适合零基础速成,如果有听不懂的可以多听几遍

https://www.bilibili.com/video/BV1Zs9VYrEgg?spm_id_from=333.788.videopod.sections&vd_source=5edde23df276e6fb4a94821fa44f38b5

目录如下:

1.Python语法基础及算法 入门 2.语法进阶&常用数据结构 &算法入门 3.贪心&排序 4.哈希&暴力&前缀 5.二分查找&二分答案 6.搜索&BFS &DFS 7.[数据结构]并查集&堆 8.动态规划 9.图论 10.数论基础&日期问题

目录

一、数论基础

(一)取模运算(数论基础中的基础)

核心运算法则(设 a, b, c 为整数,mod 为模数)

常用技巧

(二)素数相关(蓝桥杯必考)

1. 素数判定(单个数字是否为素数)

适用场景

核心优化

模板代码

2. 筛法求素数(求 1~n 内的所有素数)

埃氏筛核心思想

模板代码(求 1~n 内的素数列表 / 素数个数)

高频变式

(三)最大公约数(GCD)& 最小公倍数(LCM)

1. 最大公约数(GCD)

核心公式:欧几里得算法(辗转相除法)

模板代码(手动实现 + 内置函数,推荐内置)

2. 最小公倍数(LCM)

核心公式

模板代码

扩展

(四)快速幂(快速求 a^b % mod)

适用场景

核心思想

模板代码(迭代版,推荐,无递归深度问题)

递归版(了解即可,Python 递归深度有限)

(五)进制转换(蓝桥杯填空题必考)

1. 十进制转其他进制(d 为十进制数,≥0)

2. 其他进制转十进制(s 为其他进制字符串,可带 / 不带前缀)

模板代码(含前缀去除、结果格式化)

(六)数论高频小知识点(填空题常考)

二、日期问题

(一)核心基础:闰年判定(日期问题的前提)

闰年判定规则(满足其一即为闰年)

模板代码(手动判定 + datetime 模块判定)

(二)各月份天数(固定规律,需熟记)

模板代码(获取某年份某月份的天数)

(三)datetime 模块核心用法(蓝桥杯日期问题首选)

1. 核心类导入

2. 核心操作模板(全覆盖蓝桥杯日期考点)

(四)蓝桥杯日期问题经典题型模板(填空题必考)

题型 1:计算两个日期之间的天数差

题型 2:日期加减 k 天,求最终日期

题型 3:判断某日期是星期几

题型 4:统计某时间段内的闰年数 / 某月天数 / 星期 X 的个数

题型 5:日期合法性判断

(五)手动日期模板(了解即可,应对无模块场景)

手动实现日期 + 1 天模板

三、蓝桥杯实战技巧与避坑指南

(一)数论基础避坑点

(二)日期问题避坑点

(三)Python 性能优化(针对编程题)

(四)刷题优先级

四、总结


论文投稿: 第二届计算机视觉和增强现实国际学术会议(CVAR 2026) 大会官网:https://ais.cn/u/AbIZ7b 大会时间:2026年3月27-29日 大会地点:新加坡

一、数论基础

数论基础是蓝桥杯的基础得分点,题目难度低、套路性强,无需深入理解底层原理,只需熟记公式和模板,就能快速解题。核心考察素数相关、公约数与公倍数、快速幂、进制转换、取模运算五大类,以下逐一梳理。

(一)取模运算(数论基础中的基础)

蓝桥杯数论题几乎都涉及取模,核心是取模运算法则的应用,避免数值溢出(Python 无整数溢出,但题目常要求结果取模)。

核心运算法则(设 a, b, c 为整数,mod 为模数)
  • (a+b)%mod=(a%mod+b%mod)%mod
  • (a−b)%mod=(a%mod−b%mod+mod)%mod(+mod 避免结果为负)
  • (a×b)%mod=(a%mod×b%mod)%mod
  • 幂取模:ab%mod(用快速幂实现,避免直接计算溢出)
  • 常用技巧
    • 除法取模:需结合逆元(蓝桥杯考频低,基础题不涉及);
    • 题目要求 “结果对 x 取模” 时,每一步运算都取模,防止中间结果过大。

    (二)素数相关(蓝桥杯必考)

    素数(质数):大于 1 的自然数,除了 1 和自身,无其他正约数。核心考察素数判定、筛法求素数,其中埃氏筛是蓝桥杯首选。

    1. 素数判定(单个数字是否为素数)
    适用场景

    判断一个数 n 是否为素数,填空题 / 编程题均常考,时间复杂度 O (√n)(优化后)。

    核心优化
    • 排除偶数和小于 2 的数:n≤1 则非素数,n=2 则是素数,n 为偶数则非素数;
    • 只需遍历到√n:若 n 有大于√n 的约数,则必有对应的小于√n 的约数。
    模板代码

    def is_prime(n):
    if n <= 1:
    return False
    if n == 2:
    return True
    if n % 2 == 0:
    return False
    # 遍历奇数,从3到√n,步长2
    for i in range(3, int(n**0.5) + 1, 2):
    if n % i == 0:
    return False
    return True

    # 测试
    print(is_prime(97)) # True
    print(is_prime(100)) # False

    2. 筛法求素数(求 1~n 内的所有素数)

    蓝桥杯主要考察埃拉托斯特尼筛法(埃氏筛),代码简洁、效率高,适配 n≤1e6 的场景(蓝桥杯数据量)。

    埃氏筛核心思想
    • 初始化一个标记数组is_prime,is_prime[i] = True表示 i 是素数;
    • 从 2 开始,将每个素数的所有倍数标记为非素数;
    • 最终未被标记的数即为 1~n 内的素数。
    模板代码(求 1~n 内的素数列表 / 素数个数)

    def get_primes(n):
    if n < 2:
    return []
    is_prime = [True] * (n + 1)
    is_prime[0] = is_prime[1] = False
    for i in range(2, int(n**0.5) + 1):
    if is_prime[i]: # i是素数,标记其倍数
    is_prime[i*i : n+1 : i] = [False] * len(is_prime[i*i : n+1 : i])
    # 提取素数列表
    primes = [i for i, val in enumerate(is_prime) if val]
    return primes

    # 测试:求1~100内的素数
    primes = get_primes(100)
    print(primes)
    print(f"1~100内素数个数:{len(primes)}") # 25

    高频变式

    求 1~n 内的素数个数:直接返回len(primes)即可,填空题常考。

    (三)最大公约数(GCD)& 最小公倍数(LCM)

    1. 最大公约数(GCD)

    指两个数的所有公共约数中最大的那个,蓝桥杯必考,Python 内置math.gcd(注意:仅支持非负整数,且返回正整数)。

    核心公式:欧几里得算法(辗转相除法)

    gcd(a,b)=gcd(b,a%b),直到b=0,此时a即为 GCD。

    模板代码(手动实现 + 内置函数,推荐内置)

    import math

    # 手动实现欧几里得算法(理解用)
    def gcd(a, b):
    while b:
    a, b = b, a % b
    return a

    # 内置函数(蓝桥杯首选,简洁高效)
    # 注意:math.gcd返回非负,且若输入为0,返回另一个数
    print(math.gcd(12, 18)) # 6
    print(math.gcd(0, 5)) # 5

    2. 最小公倍数(LCM)

    指两个数的所有公共倍数中最小的那个,无内置函数,需通过 GCD 推导。

    核心公式

    lcm(a,b)=gcd(a,b)∣a×b∣​(先乘后除可能溢出,Python 无此问题,直接用)。

    模板代码

    import math

    def lcm(a, b):
    if a == 0 or b == 0:
    return 0 # 0和任何数的LCM为0
    return abs(a * b) // math.gcd(a, b) # 用整除避免浮点数

    # 测试
    print(lcm(12, 18)) # 36
    print(lcm(5, 7)) # 35

    扩展

    多个数的 GCD/LCM:依次求两两的 GCD/LCM,如gcd(a,b,c) = gcd(gcd(a,b),c)。

    (四)快速幂(快速求 a^b % mod)

    适用场景

    求ab%mod,当 b 很大时(如 b=1e9),直接计算ab会超时 / 溢出,快速幂时间复杂度 O (logb),是蓝桥杯中档题高频考点。

    核心思想

    分治:将幂次 b 拆分为二进制,把多次乘法转化为少次平方和乘法,如a5=a4×a1(5 的二进制 101)。

    模板代码(迭代版,推荐,无递归深度问题)

    def fast_pow(a, b, mod):
    """求a^b % mod,迭代版"""
    res = 1 # 结果初始化为1
    a = a % mod # 先对a取模,减少计算量
    while b > 0:
    if b % 2 == 1: # b的二进制最后一位为1,乘上当前a
    res = (res * a) % mod
    a = (a * a) % mod # a平方,b右移一位
    b = b // 2
    return res

    # 测试:求2^10 % 1000 = 1024 % 1000 = 24
    print(fast_pow(2, 10, 1000)) # 24
    # 测试:求3^999999999 % 7(b极大)
    print(fast_pow(3, 999999999, 7)) # 6

    递归版(了解即可,Python 递归深度有限)

    def fast_pow_rec(a, b, mod):
    if b == 0:
    return 1
    a = a % mod
    if b % 2 == 1:
    return (a * fast_pow_rec(a, b-1, mod)) % mod
    else:
    temp = fast_pow_rec(a, b//2, mod)
    return (temp * temp) % mod

    (五)进制转换(蓝桥杯填空题必考)

    蓝桥杯主要考察十进制与二进制 / 八进制 / 十六进制的转换,Python 内置函数可直接实现,无需手动编写算法,熟记函数即可。

    1. 十进制转其他进制(d 为十进制数,≥0)
    • 转二进制:bin(d) → 返回字符串,前缀0b;
    • 转八进制:oct(d) → 返回字符串,前缀0o;
    • 转十六进制:hex(d) → 返回字符串,前缀0x,字母为小写,大写可用upper()。
    2. 其他进制转十进制(s 为其他进制字符串,可带 / 不带前缀)

    int(s, base):base 为进制数(2/8/16),返回十进制整数。

    模板代码(含前缀去除、结果格式化)

    # 1. 十进制转其他进制
    d = 10
    bin_s = bin(d) # '0b1010'
    oct_s = oct(d) # '0o12'
    hex_s = hex(d) # '0xa'
    # 去除前缀,仅保留数字
    print(bin_s[2:]) # '1010'
    print(hex_s[2:].upper()) # 'A'(十六进制大写)

    # 2. 其他进制转十进制
    s1 = '1010' # 二进制,无前缀
    s2 = '0o12' # 八进制,带前缀
    s3 = '0xA' # 十六进制,带前缀
    print(int(s1, 2)) # 10
    print(int(s2, 8)) # 10
    print(int(s3, 16)) # 10

    # 3. 自定义进制转换(如十进制转k进制,k≤10,填空题偶考)
    def dec2k(d, k):
    if d == 0:
    return '0'
    res = ''
    while d > 0:
    res += str(d % k)
    d = d // k
    return res[::-1] # 逆序输出
    print(dec2k(10, 3)) # 101(10的3进制)

    (六)数论高频小知识点(填空题常考)

  • 奇偶性判断:n%2 == 0 为偶数,n%2 == 1 为奇数;
  • 因数分解:求 n 的所有正因数,遍历 1~√n,若 i 是 n 的因数,则 n/i 也为因数(去重); def get_factors(n):
    factors = set()
    for i in range(1, int(n**0.5)+1):
    if n % i == 0:
    factors.add(i)
    factors.add(n//i)
    return sorted(factors)
    print(get_factors(12)) # [1,2,3,4,6,12]
  • 阶乘取模:求 n! % mod,循环累乘并每一步取模;
  • 水仙花数 / 阿姆斯特朗数:n 位数字的各位 n 次方和等于自身(如 153=1³+5³+3³),遍历判断即可。
  • 二、日期问题

    日期问题是蓝桥杯填空题高频考点,少量出现在简单编程题,核心考察闰年判定、日期加减、星期计算、日期合法性判断,套路性极强,只需掌握核心规律 + 模板,注意边界处理(如 2 月 28/29 天、月份 12 个月、日期 30/31 天)即可轻松解题。

    Python 中可使用datetime模块直接处理日期(推荐,简洁高效,无边界错误),也可手动编写日期模板(应对特殊场景),以下优先讲解datetime 模块解法(蓝桥杯首选),再补充手动模板(理解用)。

    (一)核心基础:闰年判定(日期问题的前提)

    闰年判定决定 2 月的天数(28/29 天),必须熟记判定规则。

    闰年判定规则(满足其一即为闰年)
  • 能被 4 整除,且不能被 100 整除;
  • 能被 400 整除。
  • 模板代码(手动判定 + datetime 模块判定)

    import datetime

    # 手动判定闰年
    def is_leap(year):
    if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):
    return True
    return False

    # datetime模块判定(直接取年份的二月天数)
    def is_leap_datetime(year):
    # datetime.date(year,2,29)能创建则为闰年,否则抛异常
    try:
    datetime.date(year, 2, 29)
    return True
    except ValueError:
    return False

    # 测试
    print(is_leap(2024)) # True
    print(is_leap(2000)) # True
    print(is_leap(1900)) # False

    (二)各月份天数(固定规律,需熟记)

    表格

    月份平年天数闰年天数
    1/3/5/7/8/10/12 31 31
    4/6/9/11 30 30
    2 28 29
    模板代码(获取某年份某月份的天数)

    import datetime

    # 手动获取
    def get_days(year, month):
    if month in [1,3,5,7,8,10,12]:
    return 31
    elif month in [4,6,9,11]:
    return 30
    else:
    return 29 if is_leap(year) else 28

    # datetime模块获取(推荐,无需判断)
    # 思路:取下个月1号,减1天,即为当月最后一天,取日期数
    def get_days_datetime(year, month):
    if month == 12:
    next_month = 1
    next_year = year + 1
    else:
    next_month = month + 1
    next_year = year
    last_day = datetime.date(next_year, next_month, 1) – datetime.timedelta(days=1)
    return last_day.day

    # 测试
    print(get_days_datetime(2024, 2)) # 29
    print(get_days_datetime(2023, 2)) # 28

    (三)datetime 模块核心用法(蓝桥杯日期问题首选)

    Python 的datetime模块提供了date、datetime、timedelta三个核心类,可直接实现日期创建、日期加减、天数差计算、星期判断,无需手动处理边界,是蓝桥杯解决日期问题的最优方案,必须熟记核心用法。

    1. 核心类导入

    from datetime import date, timedelta
    # date:处理年月日(核心)
    # timedelta:处理时间差(天、小时等,日期问题主要用days)

    2. 核心操作模板(全覆盖蓝桥杯日期考点)

    from datetime import date, timedelta

    # 1. 创建日期对象:date(年, 月, 日),注意:参数必须合法(如2024-02-29合法,2023-02-29不合法)
    d1 = date(2024, 5, 20)
    d2 = date(2023, 12, 31)

    # 2. 获取日期的年/月/日/星期:weekday()/isoweekday()
    print(d1.year) # 2024
    print(d1.month) # 5
    print(d1.day) # 20
    # 星期判断:蓝桥杯常考,注意两个函数的区别
    # weekday():周一=0,周二=1,…,周日=6
    # isoweekday():周一=1,周二=2,…,周日=7(更符合日常习惯,推荐)
    print(d1.isoweekday()) # 1(2024-05-20是周一)

    # 3. 日期加减:日期对象 ± timedelta(days=k) → 新的日期对象
    d3 = d1 + timedelta(days=10) # 2024-05-30
    d4 = d2 – timedelta(days=1) # 2023-12-30
    print(d3) # 2024-05-30
    print(d4) # 2023-12-30

    # 4. 计算两个日期的天数差:日期对象1 – 日期对象2 → 返回timedelta对象,取days属性
    delta = d1 – d2
    print(delta.days) # 141(2023-12-31到2024-05-20的天数)
    # 注意:大日期减小日期,结果为正;反之则为负

    # 5. 日期合法性判断:创建日期时捕获ValueError异常
    def is_valid_date(year, month, day):
    try:
    date(year, month, day)
    return True
    except ValueError:
    return False
    print(is_valid_date(2024, 2, 29)) # True
    print(is_valid_date(2023, 2, 29)) # False

    (四)蓝桥杯日期问题经典题型模板(填空题必考)

    日期问题的题型高度固定,以下覆盖99% 的蓝桥杯日期考题,直接套用datetime模板即可,无需手动计算。

    题型 1:计算两个日期之间的天数差

    问题:求从 date1(y1,m1,d1)到 date2(y2,m2,d2)的天数差(含 / 不含首尾,题目会说明)。模板代码

    from datetime import date

    y1, m1, d1 = 2020, 1, 1
    y2, m2, d2 = 2024, 1, 1
    d_start = date(y1, m1, d1)
    d_end = date(y2, m2, d2)
    days = (d_end – d_start).days
    print(days) # 1461(2020是闰年,包含2020-02-29)
    # 若题目要求“不含首尾”,则days -= 1;含首尾则days += 1

    题型 2:日期加减 k 天,求最终日期

    问题:已知日期(y,m,d),加 / 减 k 天,求最终的年、月、日。模板代码

    from datetime import date, timedelta

    y, m, d = 2024, 5, 20
    k = 100
    d_init = date(y, m, d)
    d_final = d_init + timedelta(days=k) # 减k天则为 – timedelta(days=k)
    print(d_final.year, d_final.month, d_final.day) # 2024 8 28

    题型 3:判断某日期是星期几

    问题:已知日期(y,m,d),求该日期是星期几(如 “星期一”/ 数字 1-7)。模板代码

    from datetime import date

    def get_week(y, m, d):
    week_dict = {1:'星期一', 2:'星期二', 3:'星期三', 4:'星期四', 5:'星期五', 6:'星期六', 7:'星期日'}
    d_obj = date(y, m, d)
    week_num = d_obj.isoweekday()
    return week_num, week_dict[week_num]

    # 测试:2024-05-20
    print(get_week(2024, 5, 20)) # (1, '星期一')

    题型 4:统计某时间段内的闰年数 / 某月天数 / 星期 X 的个数

    问题:统计从 date1 到 date2 内的闰年数、星期 X 的个数(如周一的个数),遍历日期即可。模板代码(统计 2020-01-01 到 2024-01-01 内的闰年数 + 周一的个数)

    from datetime import date, timedelta

    d_start = date(2020, 1, 1)
    d_end = date(2024, 1, 1)
    leap_count = 0 # 闰年数
    monday_count = 0 # 周一的个数

    current = d_start
    while current <= d_end:
    # 统计闰年
    if (current.year % 4 == 0 and current.year % 100 != 0) or (current.year % 400 == 0):
    leap_count += 1
    # 统计周一(isoweekday()=1)
    if current.isoweekday() == 1:
    monday_count += 1
    # 日期+1天
    current += timedelta(days=1)

    print(f"闰年数:{leap_count}") # 2(2020、2024)
    print(f"周一的个数:{monday_count}") # 209

    题型 5:日期合法性判断

    问题:判断输入的(年、月、日)是否为合法日期(如 2023-02-29 不合法)。模板代码

    from datetime import date

    def is_valid(y, m, d):
    try:
    date(y, m, d)
    return True
    except ValueError:
    return False

    print(is_valid(2023, 2, 29)) # False
    print(is_valid(2024, 13, 1)) # False(月份13)
    print(is_valid(2024, 4, 31)) # False(4月31天)
    print(is_valid(2024, 5, 31)) # True

    (五)手动日期模板(了解即可,应对无模块场景)

    若考试中要求手动实现(极少情况),核心是模拟日期进位,如日期 + 1 天时,需判断:

  • 日期是否为当月最后一天,若是则月份 + 1,日期置 1;
  • 月份是否为 12 月,若是则年份 + 1,月份置 1;
  • 2 月的最后一天由闰年判定决定。
  • 手动实现日期 + 1 天模板

    def is_leap(year):
    return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0)

    def next_day(year, month, day):
    # 获取当月天数
    if month in [1,3,5,7,8,10,12]:
    max_day = 31
    elif month in [4,6,9,11]:
    max_day = 30
    else:
    max_day = 29 if is_leap(year) else 28
    # 日期+1
    if day < max_day:
    return year, month, day+1
    else:
    # 月份+1
    if month < 12:
    return year, month+1, 1
    else:
    # 年份+1
    return year+1, 1, 1

    # 测试:2024-02-29 +1天 → 2024-03-01
    print(next_day(2024, 2, 29)) # (2024, 3, 1)
    # 测试:2024-12-31 +1天 → 2025-01-01
    print(next_day(2024, 12, 31)) # (2025, 1, 1)

    三、蓝桥杯实战技巧与避坑指南

    (一)数论基础避坑点

  • 素数判定的边界:注意 n=2 是素数,n=1 不是素数,避免漏判;
  • math.gcd 的参数:仅支持非负整数,若输入负数,先取绝对值;
  • 快速幂的取模:每一步运算都要取模,尤其是 res 和 a 的更新,避免中间结果过大;
  • 进制转换的前缀:内置函数 bin/oct/hex 返回的字符串带前缀,填空题需去除前缀后再输出;
  • 取模的负数处理:(a – b) % mod 需加 mod 后再取模,避免结果为负(如 (5-8)%7 = (-3)%7 =4,而非 – 3)。
  • (二)日期问题避坑点

  • 闰年判定的特殊值:整百年份(如 1900、2000)必须能被 400 整除才是闰年,避免仅判断能被 4 整除;
  • datetime 的日期合法性:创建 date 对象时,参数必须是合法日期,否则抛异常,需提前判断;
  • 星期判断的函数区别:weekday () 周一为 0,isoweekday () 周一为 1,按题目要求选择,避免混淆;
  • 天数差的首尾包含:题目常考 “从 A 到 B 共多少天”(含首尾),需在天数差基础上 + 1,避免直接输出 delta.days;
  • 月份的天数:4/6/9/11 月只有 30 天,避免误判为 31 天。
  • (三)Python 性能优化(针对编程题)

  • 数论部分:筛法求素数时,用切片标记非素数(is_prime[i*i:n+1:i] = [False]*…),比循环标记快 10 倍以上;
  • 日期部分:遍历日期时,用 datetime 模块的 timedelta,比手动模拟日期进位快且不易出错;
  • 输入优化:编程题中若输入多组数据,用sys.stdin.readline替代 input,提升速度。
  • (四)刷题优先级

  • 数论基础:素数判定 / 筛法 → 最大公约数 / 最小公倍数 → 快速幂 → 进制转换 → 因数分解;
  • 日期问题:闰年判定 → 日期加减 / 天数差 → 星期判断 → 时间段统计。刷题重点:蓝桥杯历年真题的填空题,数论和日期问题的填空题占比极高,且难度低,练熟真题即可。
  • 四、总结

    数论基础和日期问题是蓝桥杯的必拿分模块,核心特点是套路性强、模板化程度高,无需深入理解底层原理,只需做到:

  • 熟记数论的核心公式和模板(素数、GCD/LCM、快速幂、进制转换);
  • 掌握日期问题的闰年判定规则和datetime 模块核心用法(首选模块解法,避免手动边界错误);
  • 注意边界处理和避坑点(如素数 n=2、闰年整百年、星期函数区别);
  • 多刷蓝桥杯历年真题的填空题,熟悉题型和出题规律。
  • 这两个模块的题目在蓝桥杯中属于 “送分题”,只要熟记模板、细心审题,就能做到零失分,为后续的中难题节省时间。

    赞(0)
    未经允许不得转载:171主机测评 » 蓝桥杯python备赛笔记之(十)数论基础 & 日期问题
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址