Skip to content

P18: math & Các hàm built-in

Tác giả: Hà Trí Kiên
Chủ đề: math module, các hàm built-in quan trọng cho thi đấu


1. Tổng quan

Module math và các hàm built-in cung cấp nhiều công cụ toán họctiện ích quan trọng cho thi đấu.


2. Module math

2.1. Các hằng số

1
2
3
4
5
6
import math

print(math.pi)       # 3.141592653589793
print(math.e)        # 2.718281828459045
print(math.inf)      # inf (vô cực)
print(math.nan)      # nan (không phải số)

2.2. Giai thừa và tổ hợp

import math

# Giai thừa
print(math.factorial(5))    # 120
print(math.factorial(0))    # 1

# Tổ hợp C(n, k) = n! / (k! * (n-k)!)
print(math.comb(10, 3))     # 120
print(math.comb(10, 0))     # 1
print(math.comb(10, 10))    # 1

# Hoán vị P(n, k) = n! / (n-k)!
print(math.perm(10, 3))     # 720
Hàm Công thức Ví dụ
math.factorial(n) \(n!\) \(5! = 120\)
math.comb(n, k) \(C(n,k) = \frac{n!}{k!(n-k)!}\) \(C(10,3) = 120\)
math.perm(n, k) \(P(n,k) = \frac{n!}{(n-k)!}\) \(P(10,3) = 720\)

2.3. GCD và LCM

1
2
3
4
5
6
7
8
9
import math

# Ước chung lớn nhất
print(math.gcd(12, 8))      # 4
print(math.gcd(0, 5))       # 5

# Bội chung nhỏ nhất (Python 3.9+)
print(math.lcm(4, 6))       # 12
print(math.lcm(12, 8))      # 24
Hàm Toán học Độ phức tạp
math.gcd(a, b) \(\gcd(a, b)\) \(O(\log(\min(a,b)))\)
math.lcm(a, b) \(\text{lcm}(a,b) = \frac{a \cdot b}{\gcd(a,b)}\) \(O(\log(\min(a,b)))\)

2.4. Căn bậc hai và lũy thừa

import math

# Căn bậc hai
print(math.sqrt(16))         # 4.0
print(math.sqrt(2))          # 1.4142135623730951

# Căn bậc 2 nguyên (Python 3.8+)
print(math.isqrt(16))        # 4
print(math.isqrt(17))        # 4 (làm tròn xuống)

# Lũy thừa
print(math.pow(2, 10))       # 1024.0 (trả về float)
print(2 ** 10)               # 1024 (trả về int)
print(pow(2, 10, 1000))      # 24 (2^10 % 1000)
Hàm Toán học Ghi chú
math.sqrt(x) \(\sqrt{x}\) Trả về float
math.isqrt(x) \(\lfloor\sqrt{x}\rfloor\) Trả về int, \(O(\log x)\)
pow(a, b, m) \(a^b \mod m\) \(O(\log b)\), rất nhanh

Giải thích ký hiệu

  • $\lfloor x \rfloor$ là hàm floor — làm tròn xuống đến số nguyên gần nhất. Ví dụ: \(\lfloor 4.7 \rfloor = 4\), \(\lfloor \sqrt{17} \rfloor = 4\).
  • $a^b \mod m$ nghĩa là tính \(a\)\(b\), rồi lấy phần dư khi chia cho \(m\). Ví dụ: \(2^{10} \mod 1000 = 1024 \mod 1000 = 24\).

2.5. Logarit

import math

# Logarit tự nhiên (ln)
print(math.log(100))         # 4.605170185988092

# Logarit cơ số 10
print(math.log10(100))       # 2.0

# Logarit cơ số 2
print(math.log2(8))          # 3.0

# Logarit cơ số tùy ý
print(math.log(8, 2))        # 3.0
Hàm Toán học Ví dụ
math.log(x) \(\ln x\) \(\ln 100 \approx 4.605\)
math.log10(x) \(\log_{10} x\) \(\log_{10} 100 = 2\)
math.log2(x) \(\log_2 x\) \(\log_2 8 = 3\)
math.log(x, base) \(\log_{\text{base}} x\) \(\log_2 8 = 3\)

2.6. Làm tròn

import math

# Làm tròn lên
print(math.ceil(3.2))        # 4
print(math.ceil(-3.2))       # -3

# Làm tròn xuống
print(math.floor(3.8))       # 3
print(math.floor(-3.8))      # -4

# Cắt phần thập phân
print(math.trunc(3.8))       # 3
print(math.trunc(-3.8))      # -3

2.7. Giá trị tuyệt đối

1
2
3
4
import math

print(math.fabs(-5))         # 5.0 (trả về float)
print(abs(-5))               # 5 (trả về int)

2.8. Tổng tích lũy

1
2
3
4
5
import math

# math.fsum: tổng chính xác cho số thực
print(math.fsum([0.1, 0.2, 0.3]))  # 0.6 (chính xác)
print(sum([0.1, 0.2, 0.3]))         # 0.6000000000000001 (có lỗi)

3. Các hàm built-in quan trọng

3.1. min, max

arr = [3, 1, 4, 1, 5, 9, 2, 6]

# min, max cơ bản
print(min(arr))              # 1
print(max(arr))              # 9

# min, max nhiều giá trị
print(min(3, 1, 4))         # 1
print(max(3, 1, 4))         # 4

# min, max với key
words = ["banana", "apple", "cherry"]
print(min(words, key=len))   # "apple"
print(max(words, key=len))   # "cherry"

# min, max của tuple
print(min(3, 1, 4))         # 1
print(max(3, 1, 4))         # 4

3.2. sum

arr = [1, 2, 3, 4, 5]

# sum cơ bản
print(sum(arr))              # 15

# sum với start
print(sum(arr, 10))          # 25 (10 + 15)

# sum generator (tiết kiệm bộ nhớ)
print(sum(i ** 2 for i in range(10)))  # 285

3.3. abs

1
2
3
print(abs(-5))               # 5
print(abs(3.14))             # 3.14
print(abs(-3.14))            # 3.14

3.4. pow

print(pow(2, 10))            # 1024
print(pow(2, 10, 1000))      # 24 (2^10 % 1000)

3.5. divmod

1
2
3
# divmod(a, b) = (a // b, a % b)
print(divmod(17, 5))         # (3, 2)
print(divmod(10, 3))         # (3, 1)

3.6. round

1
2
3
print(round(3.14159, 2))     # 3.14
print(round(3.5))            # 4 (banker's rounding)
print(round(2.5))            # 2 (banker's rounding!)

Banker's rounding

Python dùng banker's rounding (làm tròn đến số chẵn gần nhất): - round(2.5) → 2 (không phải 3!) - round(3.5) → 4

3.7. chr, ord

1
2
3
4
5
6
7
8
9
# chr: mã ASCII → ký tự
print(chr(65))               # 'A'
print(chr(97))               # 'a'
print(chr(48))               # '0'

# ord: ký tự → mã ASCII
print(ord('A'))              # 65
print(ord('a'))              # 97
print(ord('0'))              # 48

3.8. hex, oct, bin

n = 255

# Hệ thập lục phân (hex)
print(hex(n))                # '0xff'
print(f"{n:#x}")             # '0xff'
print(f"{n:x}")              # 'ff'

# Hệ bát phân (oct)
print(oct(n))                # '0o377'
print(f"{n:#o}")             # '0o377'
print(f"{n:o}")              # '377'

# Hệ nhị phân (bin)
print(bin(n))                # '0b11111111'
print(f"{n:#b}")             # '0b11111111'
print(f"{n:b}")              # '11111111'

3.9. int với base

1
2
3
4
5
6
# Chuyển từ hệ khác sang thập phân
print(int('0xff', 16))       # 255
print(int('0b1010', 2))      # 10
print(int('0o17', 8))        # 15
print(int('ff', 16))         # 255
print(int('1010', 2))        # 10

3.10. isinstance

1
2
3
4
5
6
7
x = 42
print(isinstance(x, int))           # True
print(isinstance(x, float))         # False
print(isinstance(x, (int, float)))  # True

s = "Hello"
print(isinstance(s, str))           # True

4. Pattern thường gặp trong thi đấu

4.1. Tính GCD nhiều số

1
2
3
4
5
6
import math
from functools import reduce

arr = [12, 18, 24]
result = reduce(math.gcd, arr)
print(result)  # 6

4.2. Tính LCM nhiều số

1
2
3
4
5
6
7
8
9
import math
from functools import reduce

def lcm(a, b):
    return a * b // math.gcd(a, b)

arr = [4, 6, 8]
result = reduce(lcm, arr)
print(result)  # 24

4.3. Kiểm tra số nguyên tố

1
2
3
4
5
6
7
8
9
import math

def is_prime(n):
    if n < 2:
        return False
    for i in range(2, math.isqrt(n) + 1):
        if n % i == 0:
            return False
    return True

4.4. Phân tích thừa số nguyên tố

import math

def prime_factors(n):
    factors = []
    d = 2
    while d * d <= n:
        while n % d == 0:
            factors.append(d)
            n //= d
        d += 1
    if n > 1:
        factors.append(n)
    return factors

4.5. Lũy thừa nhanh modulo

def power_mod(base, exp, mod):
    result = 1
    base %= mod
    while exp > 0:
        if exp % 2 == 1:
            result = result * base % mod
        exp //= 2
        base = base * base % mod
    return result

# Hoặc dùng pow()
print(pow(2, 10, 1000))  # 24

5. So sánh với C++

Python C++ Ghi chú
math.gcd __gcd (GCC) Cùng chức năng
math.lcm lcm (C++17)
math.sqrt sqrt
math.isqrt (int)sqrt
math.factorial Không có Phải tự cài
math.comb Không có Phải tự cài
math.log2 log2
math.ceil, math.floor ceil, floor
abs abs
min, max min, max
pow(a, b, m) Tự cài Python hỗ trợ sẵn

6. Lưu ý / Cạm bẫy hay gặp

Bẫy 1: pow trả về float

print(pow(2, 10))      # 1024 (int)
print(math.pow(2, 10)) # 1024.0 (float!)

Bẫy 2: round với banker's rounding

print(round(2.5))  # 2 (không phải 3!)
print(round(3.5))  # 4

Bẫy 3: math.sqrt trả về float

print(math.sqrt(16))   # 4.0 (float)
print(math.isqrt(16))  # 4 (int)

Bẫy 4: Chia cho 0 trong math.log

# math.log(0)  # ValueError!

7. Bài tập thực hành

Bài 1: GCD và LCM

Đọc 2 số a, b. Tính GCD và LCM.

???? tip "Lời giải"

1
2
3
4
5
import math

a, b = map(int, input().split())
print(f"GCD: {math.gcd(a, b)}")
print(f"LCM: {a * b // math.gcd(a, b)}")

Bài 2: Kiểm tra số nguyên tố

Đọc số n. Kiểm tra n có phải số nguyên tố không.

???? tip "Lời giải"

import math

n = int(input())
if n < 2:
    print("Khong phai SNT")
else:
    is_prime = True
    for i in range(2, math.isqrt(n) + 1):
        if n % i == 0:
            is_prime = False
            break
    if is_prime:
        print("SNT")
    else:
        print("Khong phai SNT")

Bài 3: Lũy thừa modulo

Đọc a, b, m. Tính (a^b) % m.

???? tip "Lời giải"

a, b, m = map(int, input().split())
print(pow(a, b, m))


8. Bài tập luyện tập

Bài Nền tảng Độ khó Chủ đề
CSES - Exponentiation CSES ⭐⭐ Lũy thừa modulo
CSES - Counting Divisors CSES ⭐⭐ Ước số

Bài viết liên quan


Bài trước: P17: bisect
Bài tiếp theo: P19: Kỹ thuật thi đấu Python →


💬 Bình luận