Professional Documents
Culture Documents
Ly Thuyet Co Ban - Python - 2
Ly Thuyet Co Ban - Python - 2
Ly Thuyet Co Ban - Python - 2
MỤC LỤC
CHỦ ĐỀ 1: LÀM QUEN PYTHON ............................................................................................................3
CHỦ ĐỀ 2: CHƯƠNG TRÌNH GIẢI BÀI TOÁN ĐƠN GIẢN .......................................................................5
CHỦ ĐỀ 3: CÂU LỆNH RẼ NHÁNH .......................................................................................................10
CHỦ ĐỀ 4 – CÂU LỆNH LẶP .................................................................................................................12
CHỦ ĐỀ 5: KIỂU DANH SÁCH – LIST ....................................................................................................14
CHỦ ĐỀ 5: KIỂU DỮ LIỆU XÂU.............................................................................................................17
CHỦ ĐỀ 6: KIỂU DỮ LIỆU TỆP..............................................................................................................21
CHỦ ĐỀ 7: CHƯƠNG TRÌNH CON ........................................................................................................23
CHỦ ĐỀ 8: MỘT SỐ THỨ CĂN BẢN KHÁC KHI BỒI DƯỠNG HSG ........................................................25
1. Số nguyên tố: ..............................................................................................................................25
2. Ước/ Bội:.....................................................................................................................................25
3. Sắp xếp:.......................................................................................................................................26
4. Tìm kiếm nhị phân: .....................................................................................................................28
5. Heap: ...........................................................................................................................................29
6. Dict – Python: .............................................................................................................................29
7. Set – Python: ...............................................................................................................................30
8. Một số Trick khác:.......................................................................................................................31
CHỦ ĐỀ 9: TĂNG TỐC CHƯƠNG TRÌNH PYTHON ...............................................................................32
CHỦ ĐỀ 10: TẠO TEST VỚI PYTHON ...................................................................................................34
CHỦ ĐỀ 11: CHẤM PYTHON TRONG THEMIS .....................................................................................36
b) Phần xử lý chính:
Phần xử lý của bài toán tính toán đơn giản thông thường có ba bước như trong ví dụ trên.
• Nhập thông tin cần thiết vào cho máy tính
• Tính toán giải quyết bài toán
• Thông báo kết quả của bài
Phần Nội dung cơ bản
- Để nhập thông tin vào từ bàn phím Python hỗ trợ cho ta hàm input()
- Hàm input() mặc định trả về một chuỗi kí tự được nhập vào từ bàn phím. Sau đây
là một số ví dụ:
Thao tác nhập Lệnh Python
Một chuỗi kí tự hoten = input()
một số nguyên x = int(input())
- Lệnh trên dùng hàm int() để chuyển xâu số
nguyên được nhập vào bởi hàm input() thành số
một số thực x = float(input())
Nhập
hai số nguyên trên hai x = int(input())
thông tin
dòng y = int(input())
Hai số nguyên cách nhau x,y = map(int, input().split())
dấu cách Trong lệnh trên:
input().split() sẽ tách chuỗi nhập thành hai
xâu số nguyên dựa vào dấu cách.
map(int, ..) sẽ chuyển hai xâu số thành 2 số
Hai số thực cách nhau dấu x,y = map(float, input().split())
cách
Ba số nguyên x,y,z = map(int, input().split())
- Python cung cấp lệnh gán để tính toán: tên biến = biểu thức
- Ví dụ tính diện tích hình chữ nhật: s = a*b
- Để viết được các biểu thức tính toán, Python cung cấp một số loại phép toán:
1. Phép toán số học: Các ví dụ dưới đây thì ta coi a = 5 và b = 7.
Phép
Mô Tả Ví Dụ
toán
Tính toán - Phép toán trừ các giá trị lại với nhau a - b = -2
Dấu < đại diện cho phép toán nhỏ hơn, nếu đối
< số 1 nhỏ hơn đối số 2 thì kết quả sẽ trả về là True a < b //True
và ngược lại sẽ là False.
Dấu > đại diện cho phép toán lớn hơn, nếu đối số
> 1 lớn hơn đối số 2 thì kết quả sẽ trả về là True và a > b //False
ngược lại sẽ là False.
Dấu > đại diện cho phép toán nhỏ hơn hoặc bằng,
<= nếu đối số 1 nhỏ hơn hoặc bằng đối số 2 thì kết a <= b //True
quả sẽ trả về là True và ngược lại sẽ là False.
Dấu > đại diện cho phép toán lớn hơn hoặc bằng,
>= nếu đối số 1 lớn hơn hoặc bằng đối số 2 thì kết a>= b //False
quả sẽ trả về là True và ngược lại sẽ là False.
3, Phép toán gán.
Phép toán gán là phép toán dùng đế gán giá trị của một đối tượng cho một đối tượng
khác. Và trong Python thì nó cũng được thể hiện giống như các ngôn ngữ khác. Và
dưới đây là 8 phép toán nằm trong dạng này mà Python hỗ trợ.
Phép
Chú Thích Ví Dụ
toán
Nếu 2 vế của phép toán này đều là True thì kết quả sẽ là True và
and
ngược lại nếu 1 trong 2 vế là False thì kết quả trả về sẽ là False.
Nếu 1 trong 2 vế là True thì kết quả trả về sẽ là True và ngược lại
or
nếu cả 2 vế là False thì kết quả trả về sẽ là False.
Đây là dạng phủ định, nếu biểu thức là True thì nó sẽ trả về là False
not
và ngược lại.
5, Phép toán bitwise.
Phép toán này thực hiện trên các bit của các giá trị. Hãy tưởng tượng mình có
2 biến a = 12 và b = 15 nhưng nếu chúng ta convert chúng sang hệ nhị phân thì 2 biến
này sẽ có giá trị như sau: a = 00001100 và b = 00001111.
Phép toán Ví Dụ
| (a | b) = 14 (00001111)
^ (a ^ b) = 3 (00000011)
>> a>>a = 0
6, Phép toán khai thác.
Phép toán này thường được dùng để kiểm tra xem 1 đối số có nằm trong 1 tập
hợp đối số hay không (list). Trong Python hỗ trợ chúng ta 2 dạng phép toán như sau:
Giả sử: a = 4, b = [1,5,7,6,9]
Phép
Chú Thích Ví Dụ
toán
for x in "banana": Duyệt qua lần lượt các chữ cái của chuỗi
print(x)
“banana”
L = ["a", "b", "c"] Lệnh break giúp dừng vòng lặp sau khi in a và
for x in L:
print(x) b ra màn hình.
if x == "b":
break
L = ["a", "b", "c"] Chỉ in a, không in b. Vì nếu x = ‘b’ thì đã ngắt
for x in L:
if x == "b": vòng lặp
break
print(x)
L = ["a", "b", "c"] Lệnh continue giúp bỏ qua 2 lệnh phía dưới
for x in L:
if x == "b": và chuyển sang lần lặp tiếp theo.
continue Kết quả sẽ in ra a và c
print(x)
s = s + x
3. Ví dụ minh hoạ:
Bài tập Code minh hoạ
Lập trình nhập vào một số nguyênn = int(input())
a = list(map(int, input().split()))
dương N và dãy số nguyên A gồm N phần tử.
amax = max(a)
Tìm phần tử lớn nhất của dãy số nguyên cùng
print(amax, end=' ')
for i in range(n):
vị trí của nó. (0 < n < 10000; |Ai| < 10^9). Nếu
có nhiều phần tử cùng có giá trị lớn nhất thìif a[i] == amax:
print(i+1)
đáp án là phần tử có vị trí bé nhất. break
Dữ liệu nhập Kết quả Hoặc cách hai như sau:
5 12 2 n = int(input())
a = list(map(int, input().split()))
1 12 -4 -3 12 print(max(a), a.index(max(a)) + 1)
Lập trình nhập vào N và dãy số A n = int(input())
a = [int(x) for x in input().split()]
gồm N phần tử (5 < N < 1000). Em hãy sắp a.sort()
xếp dãy A thành dãy số không giảm và print(*a)
thông báo dãy A ra màn hình sau khi đã sắp
Hoặc cách 2: nhanh hơn ở thao tác in:
xếp.
Dữ liệu nhập Kết quả n = int(input())
a = list(map(int, input().split()))
5 12345 a.sort()
13254 print(' '.join(str(x) for x in a))
Lập trình nhập vào mảng hai chiều gồm m m, n = map(int, input().split())
a = [[]*n for i in range(m)]
dòng n cột chỉ gồm các số nguyên. Tính
for i in range(m):
tổng các phần tử trên mỗi cột và thông báo a[i] = list(map(int, input().split()))
các tổng này ra màn hình. (1 < m, n < 100) for j in range(n):
sum = 0
Dữ liệu nhập Kết quả
for i in range(m):
23 5 sum += a[i][j]
123 7 print(sum)
456 9
• findall(): Trả về một list chứa các chuỗi con khớp theo yêu cầu thao tác
• sub(): Thay thế các chuỗi con xuất hiện trong chuỗi gốc bằng các chuỗi được chỉ định
* Những kí tự có ý nghĩa đặc biệt được sử dụng trong các hàm ReGex:
Kí tự Ý nghĩa Ví dụ
| Khớp với một trong số các điều kiện cần tìm. "an|nam"
Ví dụ: “an|nam” sẽ khớp với chuỗi kí tự chứa “an”, “nam” hoặc cả 2
* Một số chuỗi đặc biệt được sử dụng trong ReGex:
Kí tự Ý nghĩa Ví dụ
\B Khớp với các từ có “ain” xuất hiện nhưng không phải ở đầu từ r"\Bain"
Khớp với các từ có “ain” xuất hiện nhưng không phải ở cuối từ r"ain\B"
\w Trả về match khi chuỗi chứa kí tự chữ số, chữ cái, hoặc dấu gạch "\w"
dưới
\W Trả về match khi chuỗi Không chứa kí tự chữ số, chữ cái, hoặc dấu "\W"
gạch dưới
[a-zA-Z] Trả về khớp cho bất kỳ kí tự nào thuộc tập kí tự in hoa và thường
Cho xâu S gồm nhiều từ cách nhau dấu cách. Tìm a = re.findall(‘^a.*b$’, s)
và in tất cả từ bắt đầu bằng ‘P’ kết thúc bằng ‘u’. print(a)
Bạn hãy lập trình sắp xếp các số trong xâu đó tăng import re
dần nhưng vẫn giữ nguyên các kí tự chữ cái. s = input()
kt = re.findall('\D+', s)
Vd: Anh24chi12abc1cd8 so = re.findall('\d+', s)
-> Anh1chi8abc12cd24
Hàm findall(‘\D’, s) giúp ta tìm tất cả def cmp(u):
đoạn liên tiếp không chứa kí tự số. return (len(u), u)
so.sort(key=cmp)
a = []
for i in range(min(len(kt),
len(so))):
a.append(kt[i])
a.append(so[i])
if len(kt) > len(so):
a.append(kt[len(kt) - 1])
print(''.join(a))
2 24 m = int(input())
for i in range(m):
4
n = int(input())
print(Fact(n))
Viết chương trình con Prime(x) để kiểm import sys
sys.stdin = open("NTO.inp", "r")
tra x có phải là số nguyên tố hay không.
sys.stdout = open("NTO.out", "w")
Vận dụng chương trình con vừa viết lập input = sys.stdin.readline
trình nhập vào dãy số nguyên a[1], a[2]…,
a[n], đếm có bao nhiêu cặp thoả mãn điều def Prime(x):
if x <= 1:
kiện a[i] + a[j] (𝑖 ≤ 𝑗) là một số nguyên tố. return 0
NTO.INP NTO.OUT for i in range(2, int(x**0.5)+1):
4 5 if x % i == 0:
return 0
1234 return 1
n = int(input())
a = list(map(int, input().split()))
dem = 0
for i in range(n):
for j in range(i, n):
if Prime(a[i]+a[j]) == 1:
dem += 1
print(dem)
Viết chương trình con chuanHoa(s) có import sys
nhiệm vụ xoá đi các kí tự trắng dư thừa có sys.stdin = open("CHUAN.inp", "r")
sys.stdout = open("CHUAN.out", "w")
mặt trong xâu s.
Vận dụng chương trình con vừa viết để def chuanHoa(s):
đọc thông tin của các bạn học sinh, tách lấy while s.find(' ') > -1:
s = s.replace(' ', ' ')
và in ra màn hình họ đệm cùng tên của các s = s.strip()
bạn học sinh này đã chuẩn hoá và in hoa return s
mỗi đầu từ.
while True:
CHUAN.INP CHUAN.OUT
try:
Le thanh phu Thanh Phu s = input()
Tran HUNG son Hung Son s = chuanHoa(s)
vt = s.find(' ')
s = s[vt+1:]
s = s.lower()
s = s.title()
print(s)
except:
break
CHỦ ĐỀ 8: MỘT SỐ THỨ CĂN BẢN KHÁC KHI BỒI DƯỠNG HSG
1. Số nguyên tố:
Bài toán Chương trình tương ứng
Kiểm tra số nguyên tố def Prime(x):
if x <= 1:
- Thuật toán duyệt căn return 0
for i in range(2, int(x**0.5)+1):
if x % i == 0:
return 0
return 1
Kiểm tra số nguyên tố def Prime6k(x):
if x <= 1:
- Thuật toán 6k return 0
if (x == 2) or (x == 3):
return 1
if (x % 2 == 0) or (x % 3 == 0):
return 0
k, can = 5, int(math.sqrt(x))
for k in range(5, can, 6):
if (x % k == 0) or (x % (k+2) == 0):
return 0
return 1
Kiểm tra số nguyên tố https://ideone.com/j2OQOJ
- Thuật toán Rabin Miller
- Thuật này phức tạp chỉ dành
cho các bạn đam mê tìm hiểu
Sàng eratos: def eratos(m):
e = [0, 0] + [1]*m
- Tạo sàng eratos có giới hạn can = int(math.sqrt(m))
m for i in range(2, can):
if e[i] == 1:
for j in range(i*i, m, i):
e[j] = 0
return e
2. Ước/ Bội:
Ước chung lớn nhất: import math
- Tìm UCLN của hai số a và b a, b = map(int, input().split())
uc = math.gcd(a, b)
Bội chung nhỏ nhất import math
- Tìm BCNN của hai số a, b a, b = map(int, input().split())
bc = (a // math.gcd(a, b)) * b
Ước chung lớn nhất: import math
- Tìm UCLN của a[1..n] a = list(map(int, input().split()))
uc = 0
for x in a:
uc = math.gcd(uc, x)
print(uc)
Bội chung nhỏ nhất: import math
- Tìm BCNN của a[1..n] a = list(map(int, input().split()))
bc = 1
for x in a:
bc = (bc // math.gcd(bc, x)) * x
print(bc)
3. Sắp xếp:
Thao tác Lệnh tương ứng
Sắp xếp list tăng dần theo giá trị a.sort()
- List xâu thì tăng dần theo thứ tự từ
điển
Giảm dần a.sort(reverse=True)
Sắp xếp xâu tăng dần s = ''.join(sorted(s))
- Vì xâu không có hàm sort nên dùng sorted(s) sẽ tạo
ra một list kí tự tăng dần.
- ‘’.join() giúp nối list kí tự này lại thành xâu
Sắp xếp xâu giảm dần s = ''.join(sorted(s, reverse=True))
Sắp xếp list tăng dần theo một điều kiện def tongcs(u):
đặc biệt: Ví dụ sum = 0
while u > 0:
• theo tổng chữ số tăng dần sum += (u % 10)
• Cùng tổng chữ số thì giá trị tăng dần u //= 10
[12, 20, 4, 21]→[20, 12, 21,4] return sum
def cmp(u):
return (tongcs(u), u)
a.sort(key=cmp)
Cho một dãy số nguyên gồm n phần n = int(input())
tử A[1]..A[n]. Hãy Sắp xếp dãy số theo a = list(input().split())
thứ tự không giảm rồi in dãy số ra màn def cmp(u):
hình. return (len(u), u)
Ràng buộc:
a.sort(key=cmp)
• 1 <= n <= 100000 print(' '.join(x for x in a))
• 1 <= A[i] <= 10^25
- Do a[i] <= 10^25 nên phải dùng xâu để lưu trữ. Tức
mỗi phần tử của list là một xâu. Vậy phải viết hàm so
sánh, vì sort mặc định sẽ theo thứ tự từ điển.
- Hàm này trước hết sẽ so sánh theo độ dài, ngắn hơn
là số bé hơn (Vì không có số 0 ở đầu), nếu dài bằng nhau
thì số nào bé hơn sẽ bé hơn.
n = int(input())
Có n con virut, con thứ i có sức phá hoại
a = []
là a[i] và khả năng phát tán là b[i]. Hãy
for i in range(n):
sắp xếp các con virut theo thứ tự sức u, v = map(int, input().split())
phá hoại bằng hoặc tăng dần. Nếu cùng a.append([u, v])
sức phá hoại thì sắp xếp theo khả năng
def cmp(u):
phát tán tăng dần. return (u[0], u[1])
Nhập Xuất
4 11 a.sort(key=cmp)
for x in a:
51 13
print(x[0], x[1])
11 17
13 51
17
Có n con virut, con thứ i có sức phá hoại n = int(input())
là a[i] và khả năng phát tán là b[i] và khả a = []
for i in range(n):
năng bị tiêu diệt là c[i]. Hãy sắp xếp các u,v,z = map(int,input().split())
con virut theo thứ tự khả năng bị tiêu a.append([u, v, z])
diệt không giảm. Nếu cùng khả năng bị
def cmp(u):
tiêu diệt thì sắp xếp theo khả năng phát return (u[2], -u[1], -u[0])
tán không tăng. Nếu giống nhau cả khả
năng bị tiêu diệt và khả năng phát tán a.sort(key=cmp)
for x in a:
thì sắp xếp theo khả năng phá hoại
print(x[0], x[1], x[2])
không tăng.
Ví dụ: con virut (2, 5, 1) sẽ xếp trước con Hàm so sánh cmp(u):
virut (2, 4, 1); con virut (2, 4, 1) sẽ xếp - Đầu tiên so sánh theo u[2] là khả năng bị tiêu diệt bé
trước con virut (1, 4, 1). hơn đứng trước tức không giảm
- Nếu cùng u[2] thì so sánh theo -u[1] là khả năng phát
Nhập Xuất
tán bé hơn đứng trước, mà -u[1] bé hơn trước tương
4 671 đương với u[1] lớn hơn xếp trước, tức là không giảm.
111 311 - Nếu cùng hai cái đầu thì sẽ so sánh theo -u[0] bé hơn
799 111 xếp trước.
311 799
671
Tèo đã viết được một số lớn trên import functools
một cuộn giấy dài và muốn khoe với n = int(input())
anh trai Tí về thành quả vừa đạt a = []
được. Tuy nhiên, khi Tèo vừa ra khỏi for i in range(n):
s = input()
phòng để gọi anh trai thì cô em Mì a.append(s)
chạy vào phòng và xé rách cuộn giấy
def cmp(u, v):
thành một số mảnh. Kết quả là trên if u+v > v+u:
mỗi mảnh có một hoặc vài kí số theo return -1
thứ tự đã viết. if u+v == v+u:
return 0
Bây giờ Tèo không thể nhớ chính return 1
xác mình đã viết số gì. Tèo chỉ nhớ
a.sort(key=functools.cmp_to_key(cmp))
rằng đó là một số rất lớn. Để làm hài print(''.join(x for x in a))
lòng cậu em trai, Tí quyết định truy
- Theo quy định: Hàm so sánh cmp(u,v) phải trả về -1,
tìm số nào là lớn nhất mà Tèo đã có
0, 1:
thể viết lên cuộn giây trước khi bị xé.
• -1: Nếu u sắp xếp trước v
Bạn hãy giúp Tí làm việc này. • 1: Nếu u sắp xếp sau v
Ràng buộc: • 0 thì sếp đâu cũng giống nhau
• 0 < n < 5050 - Hàm trên so sánh để quyết định xâu u xếp trước xâu
v khi nào:
• Số chữ số trên mỗi mảnh giấy
• u xếp trước tạo ra xâu số: u+v
không quá 100.
• u xếp sau tạo ra xâu số: v+u
Nhập Xuất
4 66220004 - Hai xâu u+v và v+u có cùng độ dài nên xâu nào bé hơn
theo thứ tự từ điển thì số tạo thành bé hơn.
2
20
004
66
5. Heap:
- Heap là loại cấu trúc dữ liệu dạng cây, và tất cả các node trong cây đó được sắp xếp theo một thứ
tự nhất định, có thể là theo chiều tăng dần hoặc giảm dần.
- Python cung cấp thư viện heapq để thao tác với heap: Mặc định là heap min
• heapq.heapify(a) Chuyển list a thành heap
• u = heapq.heappop(hp) Lấy phần tử nhỏ nhất ra khỏi heap
• heapq.heappush(hp, u) Đưa phần tử u vào heap
- Ví dụ:
Bài tập Chương trình
Có n đống sỏi được đánh số từ 1 đến import heapq
n = int(input())
n, đống thứ i có a[i] viên sỏi. Ta có thể a = list(map(int, input().split()))
ghép hai đống sỏi với nhau thành một hp = []
đống với chi phí là tổng số sỏi của hai for x in a:
heapq.heappush(hp, x)
đống đó. chiphi = 0
Yêu cầu: Tìm cách ghép n đống sỏi while len(hp) > 1:
u = heapq.heappop(hp)
thành 1 đống duy nhất với tổng chi phí v = heapq.heappop(hp)
ghép nhỏ nhất. chiphi += (u + v)
heapq.heappush(hp, u+v)
Nhập Xuất
print(chiphi)
3 16
282
6. Dict – Python:
- Nếu từng dùng mảng đánh dấu trong Pascal thì thấy rằng đây là cách làm tuyệt vời giúp ta kiểm
tra sự tồn tại của một số rất nhanh trong O(1). Tuy nhiên mảng đánh dấu lại hạn chế bởi vì giới hạn
khai báo của mảng.
- Trong Python cung cấp kiểu Dictionary giúp ta lưu trữ nhiều phần tử, mỗi phần tử là một cặp [key
: value] tức giúp đánh dấu giá trị của key là value.
- Ví dụ: c = {1: 'Phu', ‘ab’: 5} giúp ta đánh dấu c[1] = ‘Phu’ và c[‘ab’] = 5.
- Kiểu Dict này trong Python linh động và mạnh hơn mảng đánh dấu rất nhiều.
- Một số thao tác:
• Khởi tạo một Dict rỗng: c = {}
• Thêm phần tử (Đánh dấu) c[1] = ‘Phú’
• Truy cập phần tử x trong dict c.get(x)
• Loại bỏ phần tử x khỏi dict del c[x]
• Xoá hết, làm rỗng dict c.clear()
• Lấy ra giá trị và xoá x khỏi dict u = c.pop(x)
- Bài tập ví dụ:
Bài tập Chương trình
Cho danh sách n số nguyên dương có n = int(input())
a = list(map(int, input().split()))
giá trị không quá một triệu. Lập trình tìm c = {}
số nguyên dương nhỏ nhất chưa có mặt for x in a:
trong danh sách trên. c[x] = 1
lim = max(a) + 1
Nhập Xuất for i in range(1, lim + 1):
if c.get(i) == None:
5 2 print(i)
break
53164
Cho số nguyên dương n và dãy n = int(input())
a = list(map(int, input().split()))
A gồm n số nguyên dương. Ta gọi c = {}
một số a[i] là có bạn nếu tồn tại một for x in a:
if c.get(x) != None:
vị trí j khác i và a[j] = a[i]. Hãy đếm số c[x] += 1
lượng số có bạn trong dãy số trên. else:
c[x] = 1
Nhập Xuất dem = 0
9 3 for x in c:
if c.get(x) > 1:
12 5 1 7 10 6 1 1 3 dem += c.get(x)
print(dem)
- Bạn nào đam mê tìm hiểu có thể tìm đọc thêm: Defaultdict trong thư viện collections. Defaultdict
tương tự như dict nhưng nhanh hơn và ít bị bug hơn.
7. Set – Python:
- Set trong Python là một tập các giá trị không có thứ tự. Mỗi giá trị trong set là duy nhất, không thể
lặp lại và bất biến (tức bạn không thể thay đổi giá trị các phần tử trong set). Tuy nhiên chúng ta có
thể thêm, xóa các phần tử trong set.
- Sử dụng set khi nào:
• Khi muốn quản lý một tập các đối tượng phân biệt, không lưu trùng lặp
• Thêm một phần tử tập nhanh: O(1)
• Xoá phần tử khỏi tập nhanh: O(1)
• Kiểm tra nhanh một đối tượng có thuộc tập đang lưu hay không: O(1)
- Một số thao tác
Thao tác Ví dụ
Khởi tạo set: #set rỗng:
- Sử dụng dấu {} hoặc set() S = set()
#một set kiểu numbers
- Nếu có phần tử trùng nhau thì sẽ bị loại S1 = {5,7,8,6}
bỏ chỉ giữ lại một #một set kiểu string
s2 = {"hello", "hi", "xin chao"}
#set với kiểu dữ liệu hỗn hợp
s3 = {"hello", 5, (1,5,7)}
Thêm phần tử S.add(5)
- <tên set>.add(phần tử)
Xoá phần tử: khuyên dùng discard để nếu S.discard(x)
xoá mà không có x trong set sẽ không bị lỗi.
- remove(x)
- discard(x)
Xoá toàn bộ set S.clear()
- clear()
Kiểm tra phần tử có trong set: if x in S:
- in print(‘Có’)
- not in
- Ví dụ:
Bài tập Chương trình
Sắn nhận được một vài tin nhắn từ n = int(input())
những người bạn. Một người có thể a = list(input().split())
s = set()
nhắn nhiều tin. Hãy giúp Sắn liệt kê danh kq = []
sách những người bạn đã gửi tin, mỗi for x in a:
người chỉ một lần và theo thứ tự thời if x not in s:
kq.append(x)
gian gửi sớm nhất s.add(x)
Nhập Xuất print(' '.join(x for x in kq))
5 mi hue cuc duc
mi hue mi cuc duc
Kết quả:
[1, 2, 4, 4]
[9, 8, 8]
- Cho một list, lấy ra 3 phần tử có số import collections
lần xuất hiện nhiều nhất a = list(map(int, input().split()))
b = collections.Counter(a)
- Độ phức tạp: O(nlogn) print(b.most_common(3))
Kết quả:
[(5, 6), (1, 5), (2, 4)]
- Sinh hoán vị độ dài 3: import itertools
(1, 2, 3) a = [1,2,3]
b = list(itertools.permutations(a))
(1, 3, 2) for x in b:
(2, 1, 3) print(x)
(2, 3, 1)
(3, 1, 2)
(3, 2, 1)
- Sinh tổ hợp chập 2 của 3: import itertools
(1, 2) a = [1, 2, 3]
b = list(itertools.permutations(a, 2))
(1, 3) for x in b:
(2, 1) print(x)
(2, 3)
(3, 1)
(3, 2)
def xuly():
sys.stdin = open("vidu.inp", "r")
sys.stdout = open("vidu.out", "w")
n = int(input())
a = [0]*n
for i in range(n):
a[i] = int(input())
for x in a:
if x % 2 == 0:
print(x, end=' ')
xuly()
Time xử lý: 1.05s
def xuly():
sys.stdin = open("vidu.inp", "r")
sys.stdout = open("vidu.out", "w")
input = sys.stdin.readline Lệnh thêm vào để đọc nhanh hơn
n = int(input())
a = [0]*n
for i in range(n):
a[i] = int(input())
b = []
for x in a:
if x % 2 == 0:
b.append(x)
s = ' '.join(str(x) for x in b) Nối thành xâu để hạn chế lệnh in
print(s) nhiều lần
xuly()
Time xử lý: 0.38s
- Chỉ với 3 thao tác tối ưu như trên, từ một chương trình bị quá thời gian (1.19s) đã giảm xuống
trong thời gian cho phép (0.38s) và giành trọn vẹn điểm của bài.
4. Một số trick khác:
- Bạn có thể google với từ khoá: Python performance
- Để đọc thêm một số kỹ thuật tối ưu code Python
5. Bàn thêm:
- Bạn phải chấp nhận thực tế rằng dù tối ưu đi chăng nữa thì nó vẫn còn quá chậm so với các ngôn
ngữ khác. Nên có thể sẽ chấp nhận TLE ở một số bài tập khi tham gia thi HSG.
- Các bạn khác nếu muốn mục tiêu đạt giải Nhất hoặc tham gia các kỳ thi cao hơn thì lời khuyên của
tôi là các bạn nên học thêm C++.
name = 'Tenbai'
def taoinput(itest)
sys.stdout = open(name + '.inp', 'w')
#dãy lệnh tạo ra input
sys.stdout.close()
def xuli(itest):
sys.stdin = open(name + '.inp')
sys.stdout = open(name + '.out', 'w')
#dãy lệnh bài làm
sys.stdin.close()
sys.stdout.close()
3. Ví dụ minh hoạ:
- Bài tập: TONG.*
Viết chương trình tính tổng hai số nguyên a và b được đọc từ tệp tong.inp.
Kết quả lưu vào tệp tong.out.
Ràng buộc: 60% test có: 0 ≤ 𝑎, 𝑏 ≤ 105 ; 40% test có: 0 ≤ 𝑎, 𝑏 ≤ 1012
import sys, random, os, shutil
name = 'Tong'
def ghiinput(gioihan):
a = random.randint(0, gioihan)
b = random.randint(0, gioihan)
print(a, b)
def taoinput(itest):
sys.stdout = open(name + '.inp', 'w')
if itest <= 12:
ghiinput(10**5)
else:
ghiinput(10**12)
sys.stdout.close()
def xuli(itest):
sys.stdin = open(name + '.inp')
sys.stdout = open(name + '.out', 'w')
a, b = map(int, input().split())
print(a + b)
sys.stdin.close()
sys.stdout.close()
• Giải nén file vừa tải về được một thư mục, sao chép toàn bộ các thứ trong thư mục này
• Dán vào mục C:\Program Files (x86)\Themis\PYTHON
- Nhận xét: Sử dụng PyPy cho tốc độ chấm ngang ngữa Pascal và C++. Tuy nhiên thực tế vẫn có chậm
hơn. Khi ra đề bài cho các kỳ thi mọi người nên code thử bài làm bằng C++ và Python, sau đó tiến
hành chấm thử trên Themis để xác định được một giới hạn thời gian chung phù hợp cho bài tập.
Khỏi tách riêng hay có thời gian riêng cho Python.