蓝桥杯Python赛道备赛——Day6:算术(二)(数学问题)

   本期博客是蓝桥杯备赛中算术(数学问题)的第二期,包括:快速幂算法、逆元(模意义下的倒数)、组合数计算和排列数计算。

   每一种数学问题都在给出定义的同时,给出了其求解方法的示例代码,以供低年级师弟师妹们学习和练习。

   前序知识:
(1)Python基础语法


算术(二)(数学问题)

      • 一、快速幂算法
      • 二、逆元(模意义下的倒数)
      • 三、组合数计算
      • 四、排列数计算

一、快速幂算法

1. 定义:
   快速计算大指数幂的算法。

2. 算法原理:

  • 二进制分解指数;
  • 利用幂的平方性质: a b = ( a 2 ) b 2 a^b = (a^2)^{\frac{b}{2}} ab=(a2)2b
  • 本质就是将次方分解为 1 1 1次幂和偶数次幂,随后再将偶数次幂分解为若干 2 2 2次幂。

3. 优缺点:

  • 优点:时间复杂度 O ( log ⁡ n ) O(\log n) O(logn),效率高。

4. 用途:
   大数模运算。

5. 示例代码:

# 快速幂算法
def fast_power(base, power):
    result = 1
    while power > 0:
        # 当指数为奇数时,乘一次基数
        if power % 2 == 1:
            result *= base
        # 基数平方
        base *= base
        # 指数折半(整数除法)
        power = power // 2
    return result

print(fast_power(3, 13))  # 输出:1594323

# 在竞赛中,可以使用python内置的快速幂函数pow
print(pow(3, 13))  # 输出:1594323

二、逆元(模意义下的倒数)

1. 定义:
    a MOD − 2 m o d    MOD a^{\text{MOD}-2} \mod \text{MOD} aMOD2modMOD 就是 a a a M O D MOD MOD 的逆元。

2. 算法原理——费马小定理:

  • p p p是质数时: a p − 2 ≡ a − 1   ( mod  p ) a^{p-2} \equiv a^{-1} \ (\text{mod} \ p) ap2a1 (mod p)
  • 举个例子:
    设  p = 7   ( 质数 ) ,   a = 3 \text{设 } p = 7 \ (\text{质数}), \ a = 3  p=7 (质数), a=3
    直接计算逆元: 3 ⋅ x ≡ 1   ( mod  7 ) ⇒ x = 5   ( 因为  3 ⋅ 5 = 15 ≡ 1   ( mod  7 ) ) \text{直接计算逆元:} \quad 3 \cdot x \equiv 1 \ (\text{mod} \ 7) \quad \Rightarrow \quad x = 5 \ (\text{因为} \ 3 \cdot 5 = 15 \equiv 1 \ (\text{mod} \ 7)) 直接计算逆元:3x1 (mod 7)x=5 (因为 35=151 (mod 7))
    按公式计算: 3 7 − 2 = 3 5 = 243 ⇒ x = 243 m o d    7 = 5 \text{按公式计算:} \quad 3^{7-2} = 3^5 = 243 \quad \Rightarrow \quad x=243 \mod 7 = 5 按公式计算:372=35=243x=243mod7=5

3. 优缺点:

  • 优点:计算快速;
  • 缺点:仅适用于模数为质数。

4. 用途:
   组合数模运算。

5. 示例代码:

# 逆元
MOD = 10**9+7  # 常用质数模数

def mod_inverse(a, mode):
    # 使用Python内置快速幂函数
    return pow(a, MOD-2, MOD)

print(mod_inverse(7, MOD))  # 输出:142857144(因为7*142857144 ≡1 mod 1e9+7)

三、组合数计算

1. 定义:
   从n个元素中选k个的组合方式数。

2. 算法原理:
C ( n , k ) = C ( n − 1 , k − 1 ) + C ( n − 1 , k ) C(n,k) = C(n-1,k-1) + C(n-1,k) C(n,k)=C(n1,k1)+C(n1,k)
C ( n , k ) = n ! k ! ( n − k ) ! C(n,k) = \frac{n!}{k!(n-k)!} C(n,k)=k!(nk)!n!

3. 优缺点:

  • 优点:避免阶乘计算的溢出风险;
  • 缺点:对大数需要模运算。

4. 用途:
   概率统计、排列组合问题。

5. 示例代码:

# 组合数计算
def combination(n, k):
    if k < 0 or k > n:
        return 0
    # 利用组合数的对称性减少计算量
    k = min(k, n - k)
    result = 1
    # 计算公式的乘积形式
    for i in range(1, k+1):
        # 分子:n - k + i
        # 分母:i
        result = result * (n - k + i) // i  # 注意整除顺序
    return result

print(combination(10, 3))  # 输出:120

# 在竞赛中,可以使用Python内置的组合数函数comb
from math import comb

print(comb(10, 3))  # 输出:120

四、排列数计算

1. 定义:
   从n个不同元素中取出k个元素进行排列的不同方式数。

2. 算法原理:
P ( n , k ) = n × ( n − 1 ) × ⋯ × ( n − k + 1 ) = n ! ( n − k ) ! P(n,k) = n \times (n-1) \times \dots \times (n-k+1) = \frac{n!}{(n-k)!} P(n,k)=n×(n1)××(nk+1)=(nk)!n!

  • 直接连乘法:从n开始连续乘k个数;
  • 处理特殊情况:k=0时结果为1,k>n时为0。

3. 优缺点:

  • 优点:时间复杂度O(k),避免计算完整阶乘;
  • 缺点:k较大时仍存在计算压力。

4. 用途:
   排列组合、概率计算、排序问题。

5. 示例代码:

# 排列数计算
def permutation(n, k):
    # 处理非法输入情况
    if k < 0:
        return 0
    if k == 0:
        return 1  # 空排列视为一种情况
    if k > n:
        return 0
    
    result = 1
    # 从n开始连乘k次(即n*(n-1)*...*(n-k+1))
    for i in range(n, n - k, -1):
        result *= i
    return result

# 验证示例
print(permutation(5, 2))  # 输出:20(5*4)

# 在竞赛中,可以使用Python内置的排列数函数permutations
from itertools import permutations

print(len(list(permutations('abcde', 2))))  # 输出:6('ab', 'ac', 'ba', 'bc', 'ca', 'cb')

你可能感兴趣的:(蓝桥杯备赛,蓝桥杯,python,职场和发展)