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............................................................................................................. 19

CHỦ ĐỀ 7: CHƯƠNG TRÌNH CON....................................................................................................... 21

CHỦ ĐỀ 8: MỘT SỐ THỨ CĂN BẢN KHÁC KHI BỒI DƯỠNG HSG........................................................ 23

1.  Số nguyên tố............................................................................................................................... 23

2.  Ước/ Bội:.................................................................................................................................... 23

3.  Sắp xếp:...................................................................................................................................... 24

4.  Tìm kiếm nhị phân...................................................................................................................... 26

5.  Heap........................................................................................................................................... 27

6.  Dict – Python............................................................................................................................... 27

7.  Set Python................................................................................................................................ 28

8.  Một số Trick khác:...................................................................................................................... 29

CHỦ ĐỀ 9: TĂNG TỐC CHƯƠNG TRÌNH PYTHON............................................................................... 30

CHỦ ĐỀ 10: TẠO TEST VỚI PYTHON................................................................................................... 32


CHỦ ĐỀ 1: LÀM QUEN PYTHON

1.  Công cụ lập trình:

nhiều phần mềm giúp chúng ta viết chạy chương trình viết bằng Python như:

·         Pycharm

·         Atom

·         Thony

·         Vscode

·        

Mỗi phần mềm đều có ưu nhược điểm riêng, cách cài đặt và viết chương trình cũng khác nhau. Pycharm hỗ trợ code rất tốt tuy nhiên lại quá nặng, khi chạy chiếm tầm 1GB Ram nên máy tính 4GB ram thì rất hay Lag. Atom giao diện đẹp, thư viện tiện ích phong phú tuy nhiên công cụ debug lại không đáp ứng được để dạy và học phần tìm và sửa lỗi. Thony thì rất nhẹ, khi chạy chiếm chỉ tầm 40MB bộ nhớ, tuy nhiên tiện ích rất ít công cụ debug còn quá đơn giản.

Dễ cài đặt, dễ sử dụng, chuyên nghiệp, hỗ trợ tốt khi code, hỗ trợ tốt debug, phù hợp với chuyên đề F và các kỳ thi HSG theo tôi vẫn là VScode. Khi chạy chiếm tầm 300MB bộ nhớ, tạo một thư mục code tất cả bài vào rất tiện lợi. Đặc biệt lên lớp 12 dùng vscode code luôn HTML5 CSS.

2.  Tải cài đặt phần mềm:

a)  Cài đặt Python cho Window:

·         Truy cập trang www.python.org vào mục Download, nhấn nút Download Python để tải về

Graphical user interface, application  Description automatically generated

·         Chạy file vừa tải về để cài đặt

b)  Cài đặt Vscode:

·         Vào google vào ô tìm kiếm: vscode, chọn Download ngay kết quả đầu tiên chọn tải về bản cho window.

·         Chạy file vừa tải để cài đặt:

 

Bước này chọn accept để cài đặt

Bước này chọn create a desktop icon để

thêm icon ra màn hình

·         Mở Vscode vừa cài xong, nhấn tổ hợp phím Ctrl + Shift + X, gõ python, sau đó chọn và cài đặt thêm tiện ích python này. Bước này sẽ giúp: Gợi ý lệnh khi code, hỗ trợ debug, chạy code…


3.  Chương trình Python đầu tiên

·        Nếu bạn chưa thư mục lưu trữ code hãy tạo cho mình một thư mục để lưu. Lưu ý tạo thư

mục không đặt tiếng Việt có dấu.

·        Mở Vscode, vào File chọn Open Folder mở thư mục của bạn vừa tạo bước trên.

·        Trong khung bên phải, Click chuột phải chọn New File để tạo file mới, đặt tên vidu.py

A screenshot of a computer  Description automatically generated with medium confidence

·        chương trình sau để thử:

A screenshot of a computer  Description automatically generated with medium confidence

·        Để chạy chương trình vừa viết xong: Nhấn vào biểu tượng tam giác màu trắng gần góc trên bên phải. Vscode sẽ hiển thị ra một khung mới phía dưới và chờ bạn nhập họ tên của mình. Sau khi gõ xong thì nhấn enter để xem kết quả.

 

Thông tin thêm : Để code format đẹp thì tìm vào File, chọn Preferences, chọn Settings, chọn Text Editor, chọn Formatting và tick chọn vào Format on Save. Sau khi tuỳ chọn này được bật, mỗi khi lưu bài thì Vscode format lại code theo chuẩn autopep8 rất chuyên nghiệp, ràng đẹp mắt.


CHỦ ĐỀ 2: CHƯƠNG TRÌNH GIẢI BÀI TOÁN ĐƠN GIẢN

1.  dụ:

Sau đây chương trình đơn giản giải bài toán tính và thông báo diện tích hình tròn:

Chương trình

Giải thích

Text  Description automatically generated

 

Khai báo thư viện toán học

 

Nhập bán kính vào từ bàn phím Tính diện tích hình tròn

Thông báo kết quả diện tích

2.  Các phần cụ thể:

a)  Phần khai báo thư viện:

Qua ví dụ trên ta thấy phần đầu tiên và rất quan trọng trong lập trình là khai báo thư viện. Việc khai báo thư viện giúp ta khai thác được các chương trình có sẵn trong thư viện. Hiện Python có hệ thống thư viện khổng lồ về rất nhiều lĩnh vực.

Sau đây xin giới thiệu đến các bạn thư viện math, chứa rất nhiều modul sử dụng cho các tác vụ toán học. Một số hàm toán học tiêu biểu:

Hàm

Công dụng

math.pi

Hằng số pi = 3.141592653589793

math.sqrt(x)

Trả về số thực căn bậc hai của số thực dương x. Nếu ta gọi hàm này

với số âm sẽ báo lỗi

math.trunc(x)

Trả về phần nguyên của số thực x. dụ: math.trunc(5.6) = 5

math.floor(x)

Làm tròn xuống số nguyên gần nhất. dụ: math.floor(5.9) = 5

math.ceil(x)

Làm tròn lên số nguyên gần nhất. dụ: math.ceil(5.3) = 6

math.fabs(x)

Trả về giá trị tuyệt đối của số x.

math.gcd(x, y)

Trả về ước chung lớn nhất của hai số nguyên x y.

math.pow(x, y)

Trả về số thực giá trị xy. Hàm này sai số khá lớn nên hạn chế sử

dụng. Nếu muốn tính xy của hai số nguyên thì nên dùng: x**y

math.sin(x)

Trả về giá trị lượng giác sin(x)

math.cos(x)

Trả về giá trị lượng giác cos(x)

math.tan(x)

Trả về giá trị lượng giác tan(x)

math.asin(x)

Trả về số đo U của góc sin(U) = x.

Dùng khi muốn tìm số đo góc. Lưu ý đơn vị là radian.

math.degrees(x)

Đổi đơn vị x radian sang độ. dụ: math.degrees(math.pi) = 180 độ.

math.radians(x)

Đổi đơn vị x độ sang radian. dụ: math.radians(180) = 3.14159…

math.log2(x)

Trả về logarit số 2 của x.

math.log10(x)

Trả về logarit cơ số 10 của x.

math.comb(n, k)

Trả về C(k,n) tổ hợp chập k của n. thể dùng để đếm số cách chọn

ra k vật trong n vật. dụ: math.comb(7, 5) = 21

Còn rất nhiều thư viện hữu ích khác, các bạn sẽ lần lượt tìm hiểu theo quá trình học.


b)  Phần xử chính:

Phần xử của bài toán tính toán đơn giản thông thường có ba bước như trong 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 bản

 

 

 

 

 

 

 

 

 

 

Nhập thông tin

-  Để 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 tự được nhập vào từ bàn phím. Sau đây

là một số 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())

hai số   nguyên   trên   hai

dòng

x = int(input()) y = int(input())

Hai số nguyên cách nhau dấu cách

x,y = map(int, input().split())

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

cách

x,y = map(float, input().split())

Ba số nguyên

x,y,z = map(int, input().split())

 

 

 

 

 

 

 

 

 

Tính toán

-  Python cung cấp lệnh gán để tính toán: tên biến = biểu thức

-  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 dụ dưới đây thì ta coi a = 5 b = 7.

 

Phép toán

 

Mô Tả

 

Dụ

 

+

Phép toán cộng các giá trị lại với nhau

a + b = 12

-

Phép toán trừ các giá trị lại với nhau

a - b = -2

*

Phép toán nhân các giá trị lại với nhau

a * b = 42

/

Phép toán chia cho ra số thực

a / b = 0.71428…

//

Phép toán chia lấy phần nguyên

a // b = 0

%

Phép toán chia lấy phần

a % b = 5

**

Phép toán mũ. a**b = ab

a ** b = 78125


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 2, Phép toán Quan hệ.                                                                                                    

Dạng phép toán này dùng để so sánh các giá trị với nhau kết quả của sẽ trả về True nếu đúng False nếu sai. thường được dùng trong các câu lệnh điều kiện.

Trong Python thì nó cũng tồn tại 6 dạng phép toán quan hệ cơ bản như sau: (trong các dụ dưới đây thì ta coi a giá trị là 5 b giá trị 7).

Phép        Chú Thích                                                                       Ví Dụ

toán

 

So sánh giá trị của các đối số xem bằng nhau

==            hay không.Nếu bằng nhau thì kết quả trả về sẽ         a == b // False True ngược lại sẽ False.

 

So sánh giá trị của các đối số xem khác nhau

!=             hay không.                                                                      a != b //True

Nếu khác nhau thì kết quả trả về sẽ True

ngược lại sẽ False.

 

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ề True         a < b //True

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ề True và         a > b //False

ngược lại sẽ 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 ngược lại sẽ 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 ngược lại sẽ False.

 3, Phép toán gán.                                                                                                                                                                                                                              Phép toán gán 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. trong Python thì cũng được thể hiện giống như các ngôn ngữ khác.

dưới đây 8 phép toán nằm trong dạng này Python hỗ trợ.

 

Phép toán

 

Chú Thích

 

Dụ

 

 

=

Phép toán này dùng để gán giá trị của một đối tượng cho một giá trị

 

c = a (lúc này c sẽ giá trị =

5)

 

 

+=

Phép toán này cộng rồi gắn giá trị cho đối tượng

 

c += a (giống với c = c + a)

 

 

-=

Phép toán này trừ rồi gắn giá trị cho đối tượng

 

c -= a (giống với c = c - a)

 


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


*=

Phép toán này trừ rồi gắn giá trị cho đối tượng

 

c *= a (giống với c = c * a)

 

 

/=

Phép toán này chia rồi gắn giá trị cho đối tượng

 

c /= a (giống với c = c / a)

 

 

%

Phép toán này chia hết rồi gắn giá trị cho đối tượng

 

c %= a (giống với c = c % a)

 

 

**=

Phép toán này lũy thừa rồi gắn giá trị cho đối tượng

 

c **= a (giống với c = c ** a)

 

 

//=

Phép toán này chia làm tròn rồi gắn giá trị cho đối tượng

 

c //= a (giống với c = c // a)

 

 4, Phép toán logic.                                                                                                          

Phép toán logic trong Python hoàn toàn giống như các ngôn ngữ khác. gồm có 3 kiểu cơ bản như sau:

Phép                                                        Chú Thích

toán

 

and              Nếu 2 vế của phép toán này đều True thì kết quả sẽ True ngược lại nếu 1 trong 2 vế là False thì kết quả trả về sẽ False.

 

or                 Nếu 1 trong 2 vế True thì kết quả trả về sẽ True ngược lại nếu cả 2 vế là False thì kết quả trả về sẽ False.

 

not               Đây dạng phủ định, nếu biểu thức True thì nó sẽ trả về False 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 2 biến a = 12 b = 15 nhưng nếu chúng ta convert chúng sang hệ nhị phân thì 2 biến này sẽ giá trị như sau: a = 00001100 b = 00001111.

Phép toán                                                  Ví Dụ

 

&                                          (a & b) = 12 (00001100)

 

|                                           (a | b) = 14 (00001111)

 

^                                           (a ^ b) = 2 (00000010)

 

~                                           (-a) = -13 (00001101)

 

<<                                         a<<a = 49152

 

>>                                         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ố 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 toán

 

Chú Thích

 

Dụ

 

 

in

Nếu 1 đối số thuộc một tập đối số sẽ trả về True ngược lại/

 

a in b //False

 

 

not in

Nếu 1 đối số không thuộc một tập đối số nó sẽ trả về True ngược lại/

 

a not in b //True

 

 

 

 

 

 

 

 

 

 

 

Thông báo kết quả

-  Để in thông tin Python cung cấp lệnh print()

-  Lệnh này cho phép in một hoặc nhiều giá trị ra màn hình. Các giá trị trong một lệnh in sẽ được in cách nhau một dấu cách.

-  Một số ví dụ:

 

Lệnh in

Ý nghĩa

 

print(12)

in số 12 ra màn hình

print(15, “hoà bình”)

in số 15 và chuỗi tự “hoà bình”

kết quả trên màn hình: 15 hoà bình

print(“số chẵn:”, 2)

số chẵn: 2

print(format(s, ‘.3f’))

in kết quả s ra màn hình, làm tròn 3 chữ số

thập phân

print(‘chào’ + ‘bạn’)

chàobạn

print(‘chào’, ‘bạn’)

chào bạn

print(‘chào’, end = ‘ ‘) print(‘bạn’)

-    end = để in xong nhưng không

xuống dòng chỉ in thêm một dấu cách

-  kết quả: chào bạn

print(‘chào’)

print(‘bạn’)

in ra hai dòng: chào

bạn

3.  dụ:

-  VD1: Chương trình nhập vào hai cạnh hình chữ nhập cách nhau dấu cách và tính diện tích

a, b = map(int, input().split()) s = a*b

print(s)

-   VD2: Chương trình nhập vào bán kính, tính thông báo diện tích hình tròn. Kết quả làm tròn 5 chữ số thập phân:

import math

r = int(input())

s = math.pi * r * r print(format(s, '.5f'))


CHỦ ĐỀ 3: CÂU LỆNH RẼ NHÁNH

1.  Câu lệnh if – else

- 

Text Box: if điều kiện:
câu lệnh 1 else
câu lệnh 2


pháp bản:

-  Nếu điều kiện đúng thì thực hiện câu lệnh 1 còn không sẽ thực hiện câu lệnh 2.

- 

Text Box: if điều kiện: lệnh 1
lệnh 2


Trường hợp sau: Nếu điều kiện đúng thì thực hiện hai câu lệnh. Python sử dụng thụt lề để xác định lệnh cùng khối với nhau. Nên lệnh 1 và lệnh 2 phải cùng thụt lề như nhau.

-  Trường hợp sau điều kiện đúng chỉ thực hiện câu lệnh 1 do hai lệnh này không cùng khối lệnh:

Text Box: if điều kiện: lệnh 1
lệnh 2

- 

Text Box: if điều kiện: lệnh 1
lệnh 2


Lệnh sau sẽ báo lỗi IndentationError do cấp độ thụt lề không xác định

2.  Một số ví dụ:

Ví dụ

Ý nghĩa, kết quả

a = 33

b = 45

if b > a:

print("b lớn hơn a")

b lớn hơn a

a,b = 68, 33

if b > a:

print("b lớn hơn a") else:

print("b không lớn hơn a")

a = 68 và b = 33 nên sẽ in ra: b không lớn hơn a

a = 200

b = 33

if b > a:

print("b lớn hơn a") elif a == b:

print("b bằng a") else:

print("b hơn a")

Sử dụng elif để kiểm tra điều kiện

a = 34

b = 68

print("A") if a > b else print("B")

Lệnh in kết hợp if then để kiểm tra

if a > b and c > a:

print("Thử hai điều kiện")

Biểu thức điều kiện với phép toán và

if a > b or a > c:

print("Chỉ cần một trong hai đúng")

Biểu thức điều kiện với phép toán hoặc

if x > 10:

print("Lớn hơn 10,") if x > 20:

print("và lớn hơn 20!")

Sử dụng if lồng nhau


 

else:

print("Nhưng không lớn hơn 20.")

 

a, b = 33, 45

if b > a:

print("b lớn hơn a") print("Chào bạn")

Lệnh in thứ hai cùng khối với lệnh if nên sau khi thực hiện xong lệnh if sẽ

thực hiện lệnh print(“Chào bạn)

a = int(input()) if a >= 0:

if a == 0:

print("Zero") else:

print("Số dương")

else:

print("Số âm")

-  Nhập số nguyên a vào từ bàn phím

-  Sử dụng if lồng nhau để kiểm tra thuộc loại số nào.

a = int(input()) if a == 0:

print("Zero") elif a > 0:

print("Số dương") else:

print("Số âm")

Tương đương dụ trên


CHỦ ĐỀ 4 CÂU LỆNH LẶP

1.  Lặp với số lần biết trước:

-  Khác với C++ hay Pascal, Python xác định lặp lại lần lượt từng đối tượng của một danh sách theo thứ tự của chúng trong danh sách.

for x in danhsach:

Lệnh xử

-  Python 3 cung cấp hàm range() để tạo ra danh sách các số nằm trong một phạm vi:

·         range(u, v) sẽ tạo ra một danh sách các số từ u đến v-1

·         range(u, v, w) sẽ tạo ra một danh sách các số từ u đến v-1, số sau cách số trước w đơn

vị

-  Một số ví dụ về lệnh lặp for:

Ví dụ

Ý nghĩa, kết quả

for x in [0, 1, 2]: print(x)

-  Lặp lại 3 lần

-  x lần lượt nhận giá trị 0, 1, 2.

for x in range(2, 6): print(x)

- range(2,6) trả về một đoạn gồm các số nguyên từ 2 đến 5.

- x lần lượt nhận giá trị 2, 3, 4, 5

for x in range(2, 10, 2): print(x)

range(2,10,2) trả về một đoạn gồm các

số nguyên [2, 4, 6, 8]

s = 0

for i in range(7, 3, -1): s += i

print(s)

- i lần lượt nhận giá trị 7, 6, 5, 4 (Lặp lùi)

fruits = ["Táo", "Chuối", "Đào"] for x in fruits:

print(x)

x lần lượt nhận giá trị trong một danh sách cho

trước

for x in "banana": print(x)

Duyệt qua lần lượt các chữ cái của chuỗi

banana

L = ["a", "b", "c"]

for x in L:

print(x)

if x == "b": break

Lệnh break giúp dừng vòng lặp sau khi in a

b ra màn hình.

L = ["a", "b", "c"]

for x in L:

if x == "b": break

print(x)

Chỉ in a, không in b. Vì nếu x = ‘b’ thì đã ngắt vòng lặp

L = ["a", "b", "c"]

for x in L:

if x == "b":

continue print(x)

s = s + x

Lệnh continue giúp bỏ qua 2 lệnh phía dưới chuyển sang lần lặp tiếp theo.

Kết quả sẽ in ra a c

 

2.  Lặp với số lần chưa biết trước:

-  pháp lệnh while:

While điều kiện:

Khối lệnh lặp

-  Ý nghĩa: Khi nào điều kiện còn đúng thì khối lệnh lặp vȁn còn được thực hiện


 

dụ

Ý nghĩa, kết quả

i = 1

while i < 6: print(i) i += 1

Sẽ in ra màn hình 5 dòng lần lượt 5 số: 1

2

3

4

5

x = 1

while x <= 10:

print(x, end = “)

x += 3

- sẽ in ra màn hình 4 số cách nhau dấu cách: 1 4 7 10

i = 1

while i < 6:

print(i) if i == 3:

break

i += 1

In ra màn hình ba số 1, 2, 3 trên ba dòng. Vì

khi i = 3 thì đã ngắt vòng lặp

i = 0

while i < 6:

i += 1

if i == 3:

continue

print(i)

-  Chỉ in ra màn hình các số 1, 2, 4, 5, 6.

-  Không in số 3 vì khi i = 3 thì thực hiện lệnh continue để bỏ qua các lệnh còn lại cùng khối lặp


CHỦ ĐỀ 5: KIỂU DANH SÁCH – LIST

1.  Khái niệm, khai báo:

-  Pascal hay C/C++ ta đã làm quen với khái niệm mảng một chiều, ở Python không còn khái niệm

này thay vào đó là kiểu list mạnh mẽ hơn.

-   List một danh sách các phần tử cùng kiểu hoặc khác kiểu được đánh số. Phần tử đầu tiên

được đánh chỉ số là 0. Mục tiêu dùng một biến duy nhất để lưu nhiều đối tượng.

-  Ví dụ: a = [7, 4, 9.8, ‘Chào’, ‘Phú’] dùng một biến a để quản lý và lưu trữ 5 đối tượng. Phần tử đầu tiên thể truy cập thông qua chỉ số: a[0] = 7. Phần tử thứ 5: a[4] = ‘Phú’

2.  Một số thao tác với List:

Công việc cần thực hiện

Lệnh tương ứng

Khởi tạo a là một list trống chưa phần tử

a = []

Khởi tạo list gồm 5 phần tử: a = [0, 0, 0, 0, 0]

a = [0]*5

Khởi tạo list gồm 6 phần tử:

b = [1, 2, 3, 4, 5, 6]

b = [i for i in range(1,7)]

Nhập vào list gồm các số nguyên cách nhau

dấu cách trên cùng một dòng

a = [int(x) for x in input().split()]

Nhập vào list gồm các số nguyên cách nhau

dấu cách trên cùng một dòng (Cách 2)

a = list(map(int, input().split()))

Nhập một list gồm các số thực trên một dòng

a = list(map(float, input().split()))

Nhập một list gồm n số nguyên, mỗi số trên một dòng.

a = []

for i in range(n):

a.append(int(input()))

in list a, mỗi phần tử một dòng

for x in a:

print(x)

in list a trên một dòng, các phần tử cách

nhau một dấu cách

for x in a:

print(x, end=' ')

in list a gồm các số nguyên trên một dòng, các phần tử cách nhau một dấu cách (cách 2

nhanh hơn)

print(' '.join(str(x) for x in a))

in list a gồm các chuỗi tự trên một dòng,

các phần tử cách nhau một dấu cách

print(' '.join(x for x in a))

Sao chép list a từ phần tử a[2] đến hết

b = a[2:]

Sao chép list a từ phần tử a[0] đến phần tử

a[3]

b = a[:4]

Sao chép list a từ phần tử a[3] đến a[6]

b = a[3:7]

Sao chép list a chỉ lấy a[2], a[4], a[6]

b = a[2:7:2]

Số lượng phần tử trong list

n = len(a)

Duyệt các phần tử trong list từ đầu đến cuối

for x in a:

print(x)

Thêm một phần tử vào list

a.append(x)

Thêm phần tử x vào vị trí u

a.insert(u, x)

Xoá phần tử cuối cùng khỏi list

a.pop()

Xoá phần tử đầu tiên trong list giá trị x

a.remove(x)

Xoá hết toàn bộ list

a.clear()

Đếm bao nhiêu phần tử giá trị x

mặt trong list

a.count(x)

Trả về True nếu x mặt trong list a

x in a

Trả về giá trị phần tử lớn nhất trong list

a.max()


 

Trả về giá trị phần tử nhỏ nhất trong list

a.min()

Đảo ngược toàn bộ list

a.reverse()

Sắp xếp list tăng dần

a.sort()

Sắp xếp list giảm dần

a.sort(reverse=True)

 

3.  dụ minh hoạ:

Bài tập

Code minh hoạ

Lập trình nhập vào một số nguyên dương N và dãy số nguyên A gồm N phần tử. Tìm phần tử lớn nhất của dãy số nguyên cùng vị trí của nó. (0 < n < 10000; |Ai| < 10^9). Nếu nhiều phần tử cùng giá trị lớn nhất thì

đáp án phần tử vị trí nhất.

n = int(input())

a = list(map(int, input().split())) amax = max(a)

print(amax, end=' ') for i in range(n):

if a[i] == amax: print(i+1) break

 

Dữ liệu nhập

Kết quả

 

 

5

1 12 -4 -3 12

12 2

Lập trình nhập vào N dãy số A

n = int(input())

a = [int(x) for x in input().split()] a.sort()

print(*a)

 

Hoặc cách 2: nhanh hơn thao tác in:

 

n = int(input())

a = list(map(int, input().split())) a.sort()

print(' '.join(str(x) for x in a))

gồm N phần tử (5 < N < 1000). Em hãy sắp

xếp dãy A thành dãy số không giảm

thông báo dãy A ra màn hình sau khi đã sắp

xếp.

 

Dữ liệu nhập

Kết quả

 

 

5

1 2 3 4 5

1 3 2 5 4

 

 

4.  Mảng hai chiều:

-  Ta có thể tạo list mà mỗi phần tử một list để thành ra tương đương mảng hai chiều

-  Sau đây minh hoạ thao tác nhập và in:

m, n = map(int, input().split()) a = [[]*n for i in range(m)]

for x in range(m):

a[x] = list(map(int, input().split()))

#in mảng hai chiều

print(m, n)

for x in range(m): print(*a[x])

-  Một số ví dụ:

 

Bài tập

Code minh hoạ

Cho mảng hai chiều kích thước NxN (N dòng và N cột). Lập trình nhập vào mảng này, tìm thông báo ra màn hình các số

lớn nhất trên mỗi hàng. (1 < N < 15)

n = int(input()) a = []

for i in range(n):

u = list(map(int,input().split())) a.append(u)

for i in range(n): print(max(a[i]))

 

Dữ liệu nhập

Kết quả

 

 

3

1 2 3

4 5 6

7 8 9

3

6

9


 

Lập trình nhập vào mảng hai chiều gồm m dòng n cột chỉ gồm các số nguyên. Tính tổng các phần tử trên mỗi cột thông báo

các tổng này ra màn hình. (1 < m, n < 100)

m, n = map(int, input().split()) a = [[]*n for i in range(m)] for i in range(m):

a[i] = list(map(int, input().split()))

for j in range(n): sum = 0

for i in range(m): sum += a[i][j]

print(sum)

 

Dữ liệu nhập

Kết quả

 

 

2 3

1 2 3

4 5 6

5

7

9


CHỦ ĐỀ 5: KIỂU DỮ LIỆU XÂU

1.  Khái niệm:

-  Kiểu xâu trong Python một dãy tự nằm giữa hai dấu ngoặc đơn hoặc ngoặc kép. dụ: “Chào

bạn”, ‘Ban oi’, ‘QuangTri2022’

-  thể xem xâu tự một danh sách tự liên tiếp nhau được đánh số thứ tự bắt đầu từ 0. dụ: với s = ‘THPTVinhDinh’ thì s[0] = ‘T’, s[4] = ‘V’, s[7] = ‘h’.

-  Nhập vào một xâu tự dùng hàm input(). dụ: s = input()

-  Để in một xâu tự ra màn hình ra dùng hàm print(). dụ: print(s)

-  Duyệt qua từng tự trong chuỗi lần lượt từ đầu đến hết ta thể sử dụng vòng lặp for:

for x in s:

print(s)

Hoặc duyệt theo chỉ số:

for i in range(len(s)): print(s[i])

-  Để tìm kiếm một xâu kí tự có xuất hiện trong xâu khác hay không: dùng toán tử in

if 'quang' in 'quangtri': print('có xuất hiện')

-  Để tìm vị trí xuất hiện một xâu tự trong xâu khác dùng hàm find(). Hàm này trả về vị trí xuất hiện

đầu tiên, nếu không xuất hiện sẽ trả về -1. dụ sau cho ra đáp án: Co xuat hien tai vi tri 5

s = 'QuangTri_2022'

if s.find('Tri') > -1:

print('Co xuat hien tai vi tri', s.find('Tri'))

-  Lệnh tách xâu con dựa vào kí tự quy định. dụ sau sẽ tách xâu s = ‘Quang Tri 2022’ ra thành một danh sách: a = ['Quang', 'Tri', '2022']

s = 'Quang Tri 2022' a = s.split(' ')

-  dụ sau tương tự nhưng tách căn cứ vào dấu phẩy:

s = 'Quang,Tri,2022' a = s.split(',')

2.  Một số thao tác khác trên xâu tự:

Các thao tác sau minh hoạ trên xâu s = ‘chao’

 

Thao tác

Ý nghĩa

s = ‘ban’ + ‘Toi’

Thao tác nối hai xâu thành 1. S = ‘banToi’

s = s*3

Lặp lại xâu s 3 lần. s = ‘chaochaochao’

s = s.capitalize()

In hoa tự đầu tiên của S, các tự khác giữ nguyên.

s = s.title()

In hoa kí tự đầu tiên mỗi từ. s = chao ban à Chao Ban

s = s.lower()

Chuyển toàn bộ xâu s về thành kí tự thường

s = s.upper()

Chuyển toàn bộ xâu s về thành kí tự in hoa

x = s.count(‘p’)

Đếm xem trong xâu s bao nhiêu tự ‘p’

s.isalnum()

Trả về True nếu xâu s chỉ chứa tự chữ cái chữ số

s.isalpha()

Trả về True nếu xâu s chỉ chứa tự chữ cái và không rỗng

s.isdecimal()

Trả về True nếu xâu s chỉ chứa tự số và không rỗng

s.islower()

Trả về True nếu xâu s chứa ít nhất 1 tự thường không

chứa tự in HOA

s.isupper()

Tương tự hàm trên


 

s.find(x) s.rfind(x)

Trả về vị trí đầu tiên/cuối cùng xuất hiện xâu x. Nếu không xuất

hiện thì trả về -1.

s = s.lstrip() s = s.rstrip()

s = s.trip()

Xoá hết tự trắng bên trái/phải/cả hai bên xâu s

dụ: s = s.lstrip() sẽ xoá tự trắng có bên trái xâu s

s = s.zfill(x)

Thêm vào kí tự không bên trái để xâu s độ dài x

s = ‘15’, s = s.zfill(4) às = ‘0015’

s = s.swapcase()

Đổi tự hoa thành thường thường thành hoa.

x = int(s)

int() giúp chuyển xâu số sang thành số

s = str(x)

str() chuyển số x sang thành một xâu

ord(s[i])

Lấy ra mã ascii của kí tự s[i]

chr(x)

Lấy ra tự có ascii x

r = s[:x]

Sao chép x tự đầu tiên của xâu s

r = s[x:]

Sao chép xâu s từ vị trí x đến hết xâu

r = s[3:6]

Sao chép các tự từ vị trí 3 đến 5 của xâu s

s = s[:x] + s[x+1:]

Xoá tự ở vị trí x của xâu s

s = s.replace('h', '')

Xoá hết tự ‘h của xâu s

 

3.  Một số ví dụ vận dụng:

Bài tập

Code tương ứng

Lập trình nhập vào một xâu tự,

đếm thông báo ra màn hình số lượng

tự A mặt trong xâu.

s = input() print(s.count('A'))

Một xâu được gọi xâu chuẩn nếu: không có kí tự trắng dư thừa đầu và cuối xâu; không có hai kí tự trắng liền nhau. Em hãy lập trình nhập vào một xâu in ra màn hình xâu

sau khi đã chuẩn hóa

s = input()

while s.find(' ') > -1:

s = s.replace(' ', ' ') s = s.strip()

print(s)

 

Dữ liệu nhập

Kết quả

 

 

Chao    ban

Chao ban

Lập trình nhập vào một xâu họ tên chuẩn thông báo ra màn hình tên của xâu

vừa nhập.

a = input().split(' ')

print(a[len(a) - 1])

 

Hoặc:

 

a = input().split(' ') a.reverse()

print(a[0])

 

Dữ liệu nhập

Kết quả

 

 

Le Thanh Huy

Huy


CHỦ ĐỀ 6: KIỂU DỮ LIỆU TỆP

1.  Một số khái niệm:

Về bản, cũng như trong hầu hết các ngôn ngữ lập trình, quá trình làm việc với tệp tin

thường bao gồm 3 giai đoạn sau:

·         Mở tệp tin

·         Thực hiện các hoạt động đọc, ghi dữ liệu

·         Đóng tệp tin để đảm bảo dữ liệu không bị hỏng hóc, mất mát

*  Mở tệp:

-  Để mở một file, chúng ta sử dụng hàm open với cú pháp:

Biến tệp = open("tên tệp","chế độ mở", encoding="kiểu hóa")

-  Trong đó:

·         Chế độ mở: ‘r’ để đọc, ‘w’ để ghi, ‘a’ mở để ghi thêm dữ liệu vào cuối

·         Kiểu mã hoá: Nếu đọc ghi tệp văn bản tiếng Việt không dấu thì không cần tham số này. Nếu

đọc ghi tệp tiếng Việt dấu thì dùng ‘utf-8’

-  dụ 1: Mở tệp Baitap1.inp để đọc dữ liệu

f = open("Baitap1.inp", "r")

-  dụ 2: Mở tệp baitap2.inp để đọc văn bản tiếng Việt dấu

f = open("Baitap2.inp", "r", encoding="utf-8")

-  dụ 3: Mở tệp baitap2.out để ghi kết quả

g = open("Baitap2.out", "w")

*  Đọc/ghi dữ liệu:

-  Đọc dữ liệu: Biếntệp.readline() để đọc một dòng

-  Ghi dữ liệu: Biếntệp.write(x) để ghi x vào tệp

*  Đóng tệp:

-  pháp: Biếntệp.close()

2.  Làm việc với tệp trong các kỳ thi HSG:

-   Khi vào ra tệp trong các kỳ thi, thao tác trên biến tệp rất dễ nhầm lȁn. Thay vào đó ta thể sử dụng tệp vào ra chuẩn. Để mở tệp thì trong phần đầu chương trình ta khai báo như sau:

import sys

sys.stdin = open("Baitap1.inp", "r") sys.stdout = open("Baitap1.out", "w")

-  Lệnh này chuyển hướng vào ra chuẩn thành vào ra tệp. Khi sử dụng tệp chuẩn này thì mọi thao tác nhập, xuất thông tin giống như vào ra bàn phím màn hình ta đã học từ trước đến giờ.

-   Python đọc dữ liệu từ tệp khá chậm, để đọc dữ liệu từ tệp nhanh ta chỉ cần khai báo thêm lệnh sau: input = sys.stdin.readline

3.  Một số ví dụ:

Bài tập

Code tương ứng

Dòng họ Tula vốn giàu thịnh vượng nhưng do nội chiến xảy ra họ phải chia ly. Các vị tiền bối cất châu báu vào một mật thất. Họ giao cho K (1 K 1000) người con mỗi người cất giữ một phần của mã số bí mật của kho báu. Người thứ i giữ mã khoá x[i] (1 ≤ x[i] ≤ 109).

Yêu cầu: Khi nội chiến kết thúc, hãy giúp K

người con tìm khoá để mở kho báu biết

import sys import math

sys.stdin = open("Timkhoa.inp", "r") sys.stdout = open("Timkhoa.out", "w") input = sys.stdin.readline

k = int(input())

a = list(map(int, input().split())) uc = a[0]

for x in a:

uc = math.gcd(uc, x) print(uc)


 

 

 

 

 

 

rằng khoá một số nguyên dương lớn nhất M tất cả số của K người con đều

chia hết.

 

 

TIMKHOA.INP

TIMKHOA.OUT

 

 

6

48 54 6 36 6 12

6

vương quốc NONAME người ta đưa

import sys

sys.stdin = open("HOHANG.inp", "r") sys.stdout = open("HOHANG.out", "w") input = sys.stdin.readline

T = int(input()) for i in range(T):

n = int(input())

s = input().rstrip() r = input().rstrip()

if sorted(s) == sorted(r): print(1)

else:

print(0)

 

Code trên sử dụng đọc dữ liệu theo dòng nên sẽ đọc cả dấu ‘\n’ ở cuối dòng. Nếu dữ liệu là xâu kí tự thì thêm lệnh rstrip() để loại tự này trước khi xử lý: s = input().rstrip()

ra một quy tắc đặt tên kỳ lạ: Mỗi dòng họ

chọn một dãy kí tự độ dài n chỉ gồm các

tự in hoa trong bảng chữ cái tiếng Anh. Khi

đó để đặt tên cho một người trong dòng

họ thì chỉ cần thay đổi thứ tự của các kí tự

với nhau.

Yêu cầu: Cho biết hai xâu tên của hai

người trong vương quốc, hãy kiểm tra xem

hai người này cùng dòng họ hay không.

 

HOHANG.INP

HOHANG.OUT

 

 

3

0

3

0

LLQ

1

KHQ

 

3

 

FDF

 

GDD

 

3

 

KWE

 

EKW

 

Cho tệp danh sách gồm nhiều dòng, mỗi dòng là một dãy số nguyên dương gồm 3 số. Em hãy lập trình đọc thông tin từ danh sách này, tính tổng của mỗi dãy số in kết quả ra màn hình.

TEPSO.INP                  TEPSO.OUT

5 3 5                             13

2 3 4                             9

5 4 3                             12

import sys

sys.stdin = open("TEPSO.inp", "r")

sys.stdout = open("TEPSO2.out", "w")

while True:

try:

x,y,z = map(int,input().split())

print(x + y + z)

except:

break

Do tệp không biết bao nhiêu dòng nên

dùng while để đọc. Lệnh try giúp bắt lỗi khi đọc

hết tệp để break kết thúc vòng lặp.


CHỦ ĐỀ 7: CHƯƠNG TRÌNH CON

1.  thuyết:

-  Kỹ thuật lập trình dȁn đến việc tổ chức chương trình kiểu cấu trúc modul hóa, tức là chia chương trình thành nhiều modul hay gọi là các chương trình con nhỏ hơn. Nó đem lại cho người lập trình các lợi ích:

·         Thay các đoạn trình giống nhau bằng một chương trình con, làm cho mã chương trình ngắn hơn, sáng sủa và dễ bảo dưỡng.

·         Đưa các chương trình con đã kiểm tra vào thư viện (library) để khi lập trình mới thì chỉ cần liên kết tới thư viện đó.

·         Những chương trình lớn được thiết kế dạng cấu trúc tốt thể trao cho các nhóm người lập trình khác nhau lập trình, đôi khi có thể thuê người làm thêm viết các chương trình con không quá phức tạp.

-  Python hỗ trợ hai loại chương trình con:

·         Hàm trả về giá trị

·         Hàm không trả về giá trị

-  pháp:

def <tên hàm>(<danh sách tham số>):

Dãy lệnh của hàm

Return [giá trị trả về]

-  Trong đó:

·         Danh sách tham số: có thể có hoặc không

·         Giá trị trả về : Tuỳ theo chương trình con, nếu không cần trả về giá trị thì không cần cái

này.

-  Lời gọi chương trình con: Một chương trình con có thể được thực hiện với nhiều giá trị khác nhau do chương trình truyền vào thông qua lời gọi hàm.

2.  Một số ví dụ:

 

Bài tập

Code tương ứng

Xây dựng hàm yêu cầu người dùng nhập họ tên rồi đưa ra lời chào.

Hàm này không có tham số, nên muốn sử dụng hàm này sẽ gọi:

chaomung()

def chaomung():

ten = input("Bạn tên gì: ") print("Chào bạn", ten) return

Xây dựng hàm trả về giá trị là tổng hai số nguyên.

Hàm này có tham số nên khi gọi phải đầy đủ hai tham số như khai báo. dụ:

s = tong(3, 5)

Hoặc

print(tong(a, b))

def tong(u, v): s = u + v return s

Hãy mô tả hàm Fact(n) để tính giá trị n giai thừa. (0 < N < 200)

Cho một danh sách có dòng đầu tiên là số M, m dòng tiếp theo mỗi dòng một số nguyên dương N. Lập trình đọc dữ liệu từ danh sách, tính giai thừa của m số đó

thông báo kết quả.

import sys

sys.stdin = open("Fact.inp", "r") sys.stdout = open("Fact.out", "w") input = sys.stdin.readline

 

def Fact(n):

gt = 1

for i in range(1, n+1): gt *= i

return gt

 

Fact.INP

Fact.OUT

 

 

3

2


 

 

 

 

 

 

 

 

 

 

 

 

 


2

4

24

 

m = int(input()) for i in range(m):

n = int(input()) print(Fact(n))

 

Viết chương trình con Prime(x) để kiểm tra x có phải là số nguyên tố hay không.

Vận dụng chương trình con vừa viết lập 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 kiện a[i] + a[j] (𝑖 𝑗) một số nguyên tố.

NTO.INP                   NTO.OUT

4                                 5

1 2 3 4

import sys

sys.stdin = open("NTO.inp", "r") sys.stdout = open("NTO.out", "w") input = sys.stdin.readline

 

def Prime(x):

if x <= 1:

return 0

for i in range(2, int(x**0.5)+1): if x % i == 0:

return 0

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ó nhiệm vụ xoá đi các kí tự trắng dư thừa có mặt trong xâu s.

Vận dụng chương trình con vừa viết để đọc thông tin của các bạn học sinh, tách lấy và in ra màn hình họ đệm cùng tên của các bạn học sinh này đã chuẩn hoá và in hoa mỗi đầu từ.

CHUAN.INP              CHUAN.OUT

Le    thanh     phu        Thanh Phu

Tran    HUNG     son       Hung Son

import sys

sys.stdin = open("CHUAN.inp", "r") sys.stdout = open("CHUAN.out", "w")

 

def chuanHoa(s):

while s.find(' ') > -1:

s = s.replace(' ', ' ') s = s.strip()

return s

 

while True: try:

s = input()

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ố

- Thuật toán duyệt căn

def Prime(x):

if x <= 1:

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ố

- Thuật toán 6k

def Prime6k(x): if x <= 1:

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ố

-  Thuật toán Rabin Miller

-  Thuật này phức tạp chỉ dành cho các bạn đam tìm hiểu

https://ideone.com/j2OQOJ

Sàng eratos:

- Tạo sàng eratos giới hạn m

def eratos(m):

e = [0, 0] + [1]*m

can = int(math.sqrt(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:

- Tìm UCLN của hai số a b

import math

a, b = map(int, input().split())

uc = math.gcd(a, b)

Bội chung nhỏ nhất

- Tìm BCNN của hai số a, b

import math

a, b = map(int, input().split())

bc = (a // math.gcd(a, b)) * b

Ước chung lớn nhất:

- Tìm UCLN của a[1..n]

import math

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:

- Tìm BCNN của a[1..n]

import math

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ị

- List xâu thì tăng dần theo thứ tự từ điển

a.sort()

Giảm dần

a.sort(reverse=True)

Sắp xếp xâu tăng dần

s = ''.join(sorted(s))

-  xâu không 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 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

đặc biệt: Ví dụ

·         theo tổng chữ số tăng dần

·         Cùng tổng chữ số thì giá trị tăng dần [12, 20, 4, 21]à[20, 12, 21,4]

def tongcs(u): sum = 0 while u > 0:

sum += (u % 10) u //= 10

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 tử A[1]..A[n]. Hãy Sắp xếp dãy số theo thứ tự không giảm rồi in dãy số ra màn hình.

Ràng buộc:

·         1 <= n <= 100000

·         1 <= A[i] <= 10^25

n = int(input())

a = list(input().split())

 

def cmp(u):

return (len(u), u)

 

a.sort(key=cmp)

print(' '.join(x for x in a))

 

-   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, 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

số hơn (Vì không số 0 đầu), nếu dài bằng nhau thì số nào hơn sẽ hơn.

n con virut, con thứ i sức phá hoại là a[i] và khả năng phát tán là b[i]. Hãy sắp xếp các con virut theo thứ tự sức phá hoại bằng hoặc tăng dần. Nếu cùng sức phá hoại thì sắp xếp theo khả năng

phát tán tăng dần.

n = int(input()) a = []

for i in range(n):

u, v = map(int, input().split()) a.append([u, v])

 

def cmp(u):

return (u[0], u[1])

 

a.sort(key=cmp) for x in a:

print(x[0], x[1])

 

Nhập

Xuất

 

 

4

5 1

1 1

1 3

1 1

1 3

1 7

5 1


 

 

1 7

 

 

 

n con virut, con thứ i sức phá hoại a[i] khả năng phát tán b[i] khả năng bị tiêu diệt là c[i]. Hãy sắp xếp các con virut theo thứ tự khả năng bị tiêu diệt không giảm. Nếu cùng khả năng bị tiêu diệt thì sắp xếp theo khả năng phát 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 thì sắp xếp theo khả năng phá hoại không tăng.

dụ: con virut (2, 5, 1) sẽ xếp trước con virut (2, 4, 1); con virut (2, 4, 1) sẽ xếp

trước con virut (1, 4, 1).

n = int(input()) a = []

for i in range(n):

u,v,z = map(int,input().split()) a.append([u, v, z])

 

def cmp(u):

return (u[2], -u[1], -u[0])

 

a.sort(key=cmp) for x in a:

print(x[0], x[1], x[2])

 

Hàm so sánh cmp(u):

-  Đầu tiên so sánh theo u[2] là khả năng bị tiêu diệt bé 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 tán bé hơn đứng trước, mà -u[1] bé hơn trước tương đương với u[1] lớn hơn xếp trước, tức không giảm.

-  Nếu cùng hai cái đầu thì sẽ so sánh theo -u[0] bé hơn xếp trước.

 

Nhập

Xuất

 

 

4

1 1 1

7 9 9

3 1 1

6 7 1

6 7 1

3 1 1

1 1 1

7 9 9

Tèo đã viết được một số lớn trên một cuộn giấy dài và muốn khoe với anh trai về thành quả vừa đạt được. Tuy nhiên, khi Tèo vừa ra khỏi phòng để gọi anh trai thì cô em Mì chạy vào phòng và xé rách cuộn giấy thành một số mảnh. Kết quả là trên mỗi mảnh một hoặc vài số theo thứ tự đã viết.

Bây giờ Tèo không thể nhớ chính xác mình đã viết số gì. Tèo chỉ nhớ rằng đó là một số rất lớn. Để làm hài lòng cậu em trai, Tí quyết định truy tìm số nào là lớn nhất mà Tèo đã có thể viết lên cuộn giây trước khi bị xé. Bạn hãy giúp làm việc này.

Ràng buộc:

·        0 < n < 5050

·        Số chữ số trên mỗi mảnh giấy không quá 100.

import functools

 

n = int(input()) a = []

for i in range(n): s = input() a.append(s)

 

def cmp(u, v):

if u+v > v+u:

return -1 if u+v == v+u:

return 0

return 1

 

a.sort(key=functools.cmp_to_key(cmp)) print(''.join(x for x in a))

 

-   Theo quy định: Hàm so sánh cmp(u,v) phải trả về -1, 0, 1:

·         -1: Nếu u sắp xếp trước v

·         1: Nếu u sắp xếp sau v

·         0 thì sếp đâu cũng giống nhau

-  Hàm trên so sánh để quyết định xâu u xếp trước xâu

v khi nào:

·         u xếp trước tạo ra xâu số: u+v

·         u xếp sau tạo ra xâu số: v+u

 

Nhập

Xuất

 


 

 

 

 

 

 

 


4

2

20

004

66

66220004

 

- Hai xâu u+v v+u cùng độ dài nên xâu nào hơn theo thứ tự từ điển thì số tạo thành hơn.

 

4.  Tìm kiếm nhị phân:

-  thư viện bisect cung cấp hai hàm tìm kiếm nhị phân rất hay:

·         u = bisect.bisect_left(a, x) : Trả về vị trí nhất trong a thoả mãn 𝑎[𝑢] 𝑥. Nếu tất cả phần tử trong a đều hơn x thì sẽ trả về u = len(a) + 1.

·         u = bisect.bisect_right(a, x) : Trả về vị trí nhất trong a thoả mãn 𝑎[𝑢] > 𝑥. Nếu tất cả phần tử trong a đều hơn x thì sẽ trả về u = len(a) + 1.

 

Thao tác

Lệnh tương ứng

Bạn được cho hai dãy số nguyên A và B, mỗi dãy N phần tử. Nhiệm vụ của bạn đếm xem bao nhiêu phần tử của dãy A xuất hiện trong dãy B. (𝑁 ≤ 105) Nhập                        Xuất

5                              4

2 3 1 4 5

1 2 3 4 8

import bisect

n = int(input())

a = list(map(int, input().split()))

b = list(map(int, input().split())) b.sort()

dem = 0

for x in a:

u = bisect.bisect_left(b, x) if u < len(b) and b[u] == x:

dem += 1

print(dem)

Nhân dịp tết trung thu, Nam được bố mẹ cho đi dự lễ hội đêm trăng rằm. Tại lễ hội này nam đã tích cực tham gia các trò chơi giành được X điểm thưởng. Nam dùng X điểm thưởng này để đổi quà. Ban tổ chức có N món quà khác nhau, món thứ i có giá trị A[i] điểm. Với số điểm X Nam quyết định sẽ đổi hai món quà khác nhau tổng giá trị lớn nhất có thể nhưng không vượt quá X. Bạn hãy xác định giúp Nam tổng giá trị quà Nam đổi

được là bao nhiêu. (𝑁 105)

import bisect

n, x = map(int, input().split())

a = list(map(int, input().split())) a.sort()

#a[i] + a[j] <= X --> a[j] <= X - a[i]

qua = 0

for i in range(n):

j = bisect.bisect_right(a, x - a[i]) - 1 if i < j and j < n:

qua = max(qua, a[i] + a[j]) print(qua)

 

Nhập

Xuất

 

 

6 18

5 3 10 2 4 9

15


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, thể 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

-  dụ:

Bài tập

Chương trình

Có n đống sỏi được đánh số từ 1 đến n, đống thứ i có a[i] viên sỏi. Ta có thể ghép hai đống sỏi với nhau thành một đống với chi phí là tổng số sỏi của hai đống đó.

Yêu cầu: Tìm cách ghép n đống sỏi

thành 1 đống duy nhất với tổng chi phí ghép nhỏ nhất.

import heapq

n = int(input())

a = list(map(int, input().split())) hp = []

for x in a:

heapq.heappush(hp, x) chiphi = 0

while len(hp) > 1:

u = heapq.heappop(hp) v = heapq.heappop(hp) chiphi += (u + v) heapq.heappush(hp, u+v)

print(chiphi)

 

Nhập

Xuất

 

 

3

2 8 2

16

 

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ử một cặp [key

: value] tức giúp đánh dấu giá trị của key value.

-  dụ: c = {1: 'Phu', ‘ab’: 5} giúp ta đánh dấu c[1] = ‘Phu’ c[‘ab’] = 5.

-  Kiểu Dict này trong Python linh động 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 dụ:

Bài tập

Chương trình

Cho danh sách n số nguyên dương giá trị không quá một triệu. Lập trình tìm số nguyên dương nhỏ nhất chưa mặt trong danh sách trên.

Nhập                        Xuất

n = int(input())

a = list(map(int, input().split())) c = {}

for x in a:

c[x] = 1 lim = max(a) + 1

for i in range(1, lim + 1): if c.get(i) == None:


 

 

5

5 3 1 6 4

2

 

print(i) break

Cho số nguyên dương n dãy A gồm n số nguyên dương. Ta gọi một số a[i] là có bạn nếu tồn tại một vị trí j khác i a[j] = a[i]. Hãy đếm số lượng số bạn trong dãy số trên.

Nhập                        Xuất

9                              3

12 5 1 7 10 6 1 1 3

n = int(input())

a = list(map(int, input().split())) c = {}

for x in a:

if c.get(x) != None: c[x] += 1

else:

c[x] = 1

dem = 0 for x in c:

if c.get(x) > 1: dem += c.get(x)

print(dem)

 

7. 

 

 

 

 

 

 
Set Python:

-  Set trong Python một tập các giá trị không thứ tự. Mỗi giá trị trong set 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 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 thuộc tập đang lưu hay không: O(1)

-  Một số thao tác

Thao tác

dụ

Khởi tạo set:

-  Sử dụng dấu {} hoặc set()

-   Nếu phần tử trùng nhau thì sẽ bị loại bỏ chỉ giữ lại một

#set rỗng:

S = set()

#một set kiểu numbers S1 = {5,7,8,6}

 

#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ử

- <tên set>.add(phần tử)

S.add(5)

Xoá phần tử: khuyên dùng discard để nếu xoá không x trong set sẽ không bị lỗi.

-  remove(x)

-  discard(x)

S.discard(x)

Xoá toàn bộ set

- clear()

S.clear()

Kiểm tra phần tử có trong set:

-  in

-  not in

if x in S:

print(‘Có’)


-  dụ:

Bài tập

Chương trình

Sắn nhận được một vài tin nhắn từ những người bạn. Một người thể nhắn nhiều tin. Hãy giúp Sắn liệt danh sách những người bạn đã gửi tin, mỗi người chỉ một lần theo thứ tự thời

gian gửi sớm nhất

n = int(input())

a = list(input().split()) s = set()

kq = []

for x in a:

if x not in s: kq.append(x) s.add(x)

print(' '.join(x for x in kq))

 

Nhập

Xuất

 

 

5

mi hue mi cuc duc

mi hue cuc duc

 

8.  Một số Trick khác:

 

Bài tập

Chương trình

-  Cho một List, lấy ra 4 số nhất, 3 số lớn nhất

-  Độ phức tạp: O(nlogn)

import heapq

a = list(map(int, input().split())) print(heapq.nsmallest(4, a)) print(heapq.nlargest(3, a))

 

Kết quả:

[1, 2, 4, 4]

[9, 8, 8]

-  Cho một list, lấy ra 3 phần tử số lần xuất hiện nhiều nhất

-  Độ phức tạp: O(nlogn)

import collections

a = list(map(int, input().split())) b = collections.Counter(a) print(b.most_common(3))

 

Kết quả:

[(5, 6), (1, 5), (2, 4)]

- Sinh hoán vị độ dài 3: (1, 2, 3)

(1, 3, 2)

(2, 1, 3)

(2, 3, 1)

(3, 1, 2)

(3, 2, 1)

import itertools a = [1,2,3]

b = list(itertools.permutations(a)) for x in b:

print(x)

- Sinh tổ hợp chập 2 của 3: (1, 2)

(1, 3)

(2, 1)

(2, 3)

(3, 1)

(3, 2)

import itertools a = [1, 2, 3]

b = list(itertools.permutations(a, 2)) for x in b:

print(x)


CHỦ ĐỀ 9: TĂNG TỐC CHƯƠNG TRÌNH PYTHON

-  Bản Python dành cho Window và phần mềm chấm Themis mới nhất 1.98 là bản Python 3.x đang sử dụng chế độ thông dịch nên việc thực hiện chương trình là rất chậm so với ngôn ngữ khác như Pascal hay C++.

-  Tuy nhiên ta thể tăng tốc chương trình bằng một số trick để chương trình chạy nhanh hơn, tránh quá giới hạn thời gian.

-   Các ví dụ sau được thực hiện trên máy tính có cấu hình: CPU i3 10105f, DDRAM4 8GB, SSD 256. Tính thời gian bằng thư viện time của Python.

-  Bài tập: Đọc từ tệp input 106 số nguyên dương có giá trị không quá 109. Lọc ra danh sách số chẵn ghi vào tệp output, các số cách nhau dấu cách.

1.  Sử dụng chương trình con biến cục bộ:

-  Sử dụng chương trình con làm chương trình chạy nhanh hơn

-  Sử dụng biến cục bộ cho tốc độ xử lý nhanh hơn

Chương trình chậm

Chương trình nhanh hơn

import sys, time

 

sys.stdin = open("vidu.inp", "r") sys.stdout = open("vidu.out", "w") n = int(input())

a = []

for i in range(n): a.append(int(input()))

for x in a:

if x % 2 == 0: print(x, end=' ')

 

import sys, time

 

def xuly():

sys.stdin = open("vidu.inp", "r") sys.stdout = open("vidu.out", "w") n = int(input())

a = []

for i in range(n): a.append(int(input()))

for x in a:

if x % 2 == 0: print(x, end=' ')

xuly()

 

Time xử (xấp xỉ): 1.19s

Time xử lý: 1.07s

2.  Nhập mảng nhanh hơn:

-  Khi đã biết kích thước mảng thì nên khai báo sẵn thay dùng append

Chương trình nhanh hơn

 

import sys, time

 

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


3.  Đọc ghi dữ liệu nhanh hơn:

-   Để đọc dữ liệu nhanh hơn: Ta nên sử dụng sys.stdin.readline thay vì sử dụng hàm input() mặc định. Để sử dụng ta chỉ cần thêm vào lệnh input = sys.stdin.readline sau khi mở tệp. Lưu ý: Khi thêm lệnh này cần hết sức cẩn thận vì sẽ đọc nguyên dòng và đọc cả kí tự xuống dòng là ‘\n’ ở cuối. Nếu đọc số thì không sao, đọc xâu thì cần loại nó đi bằng cách input().replace('\n', '').

-  Để ghi dữ liệu nhanh hơn: Hạn chế ghi nhiều lần: bằng cách nối thành một xâu rồi ghi một lần.

Chương trình nhanh hơn

 

 

import sys, time

 

def xuly():

sys.stdin = open("vidu.inp", "r") sys.stdout = open("vidu.out", "w") input = sys.stdin.readline

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) print(s)

 

xuly()

 

 

 

 

 

 

 

Lệnh thêm vào để đọc nhanh hơn

 

 

 

 

 

 

 

 

Nối thành xâu để hạn chế lệnh in nhiều lần

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 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 tối ưu đi chăng nữa thì 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++.


CHỦ ĐỀ 10: TẠO TEST VỚI PYTHON

1.  Thư viện random:

-  Python thư viện random bạn có thể sử dụng để tạo ra các số ngȁu nhiên.

-  Một số thao tác:

·         random.randint(u, v)       Trả về một số nguyên ngȁu nhiên trong đoạn [u, v]

·         random.random()            Trả về một số thực thuộc đoạn [0, 1]

·         random.uniform(2, 6)       Trả về số thực thuộc đoạn [2, 6]

·         random.choice(a)           Lấy ngȁu nhiên một phần tử thuộc list a

·         random.sample(a, k=3)      Tạo một list gồm 3 phần tử ngȁu nhiên từ list a

·         random.shuffle(a)          Xáo trộn ngȁu nhiên list a

·         random.getrandbits(2)      Tạo một số ngȁu nhiên có 2 bit

·        

2. 
Text Box: import sys, random, os, shutil 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()

#Di chuyển 2 tệp vào đúng thư mục test def movefile(itest):
num = '0' * (3 - len(str(itest))) + str(itest) newpath = name + '/Test' + num shutil.rmtree(newpath, ignore_errors=True) os.makedirs(newpath)
shutil.move(name + '.inp', newpath + "/" + name + '.inp') shutil.move(name + '.out', newpath + "/" + name + '.out')

#Phần chính: gọi tạo ra 20 test
for itest in range(1, 21): taoinput()
xuli(itest)
movefile(itest)

Template tạo test:


3.  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()

 

# Di chuyển 2 tệp vào đúng thư mục test

def movefile(itest):

num = '0' * (3 - len(str(itest))) + str(itest) newpath = name + '/Test' + num shutil.rmtree(newpath, ignore_errors=True) os.makedirs(newpath)

shutil.move(name + '.inp', newpath + "/" + name + '.inp') shutil.move(name + '.out', newpath + "/" + name + '.out')

 

# Phần chính: gọi tạo ra 20 test

for itest in range(1, 21): taoinput(itest) xuli(itest) movefile(itest)