Tài liệu Bồi dưỡng học sinh giỏi Tin học bậc THCS - Chuyên đề: Giải đề thi học sinh giỏi bằng ngôn ngữ lập trình Python 3.x - Nguyễn Tấn Phong

Tài liệu Bồi dưỡng học sinh giỏi Tin học bậc THCS - Chuyên đề: Giải đề thi học sinh giỏi bằng ngôn ngữ lập trình Python 3.x - Nguyễn Tấn Phong

Câu 2: Tìm số tự mãn trong dãy

Qui ước: Số tự mãn bậc 3 là những số bằng tổng lập phương các chữ số

của nó. Ví dụ: Số 153 là số tự mãn vì 153 = 13 + 53 + 33.

Cho dãy gồm N phần tử là số nguyên dương A1, A2, . , An; (0<>

0

* Dữ liệu vào từ file: SOTUMAN.INP

- Dòng đầu tiên chứa số nguyên dương N.

- Dòng thứ hai chứa N số nguyên dương, các số cách nhau một khoảng trắng.

* Kết quả ra file: SOTUMAN.OUT

- Dòng đầu tiên ghi các số tự mãn tìm được theo thứ tự tăng dần, các số cách

nhau một khoảng trắng.

pdf 56 trang Hoàng Giang 31/05/2022 108962
Bạn đang xem 20 trang mẫu của tài liệu "Tài liệu Bồi dưỡng học sinh giỏi Tin học bậc THCS - Chuyên đề: Giải đề thi học sinh giỏi bằng ngôn ngữ lập trình Python 3.x - Nguyễn Tấn Phong", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
Tác giả: NGƯT Nguyễn Tấn Phong – Trường THCS Đồng Nai, Cát Tiên, Lâm Đồng 
TÀI LIỆU BỒI DƯỠNG HỌC SINH GIỎI TIN HỌC BẬC THCS 
CHUYÊN ĐỀ 
GIẢI ĐỀ THI HỌC SINH GIỎI 
BẰNG NNLT PYTHON 3.x 
Tác giả: NGƯT Nguyễn Tấn Phong 
 Đơn vị: Trường THCS Đồng Nai, huyện Cát Tiên, tỉnh Lâm Đồng 
1. ĐỀ THI HSG HUYỆN CÁT TIÊN – NĂM HỌC 2020 – 2021 
Câu 1: Tính tổng 
Viết chương trình tính tổng: 
2 2 2
1 1 1
S=1+ + +...+
2 3 n
* Dữ liệu vào từ file: TONG.INP 
 - Dòng đầu tiên ghi số tự nhiên n. 
 * Kết quả ra file: TONG.OUT 
 - Dòng đầu tiên ghi số thực là tổng S, làm tròn đến hai chữ số thập phân. 
 Ví dụ: 
TONG.INP TONG.OUT 
3 1,361 
4 1,424 
Phân tích: Kết quả file OUT dùng dấu phẩy (,) để ngăn cách phần nguyên và phần 
thập phân và làm tròn 3 chữ số thập phân. 
Đây được xem là một “bẩy” kĩ năng đọc và phân tích đề bài (còn gọi là “bẩy” 
cá tính thí sinh). 
Code tham khảo: 
1 
2 
3 
4 
5 
6 
#Đọc dữ liệu vào từ file INP 
fi = open('tong.inp') 
n = int(fi.read()) 
fi.close() 
#Thuật toán 
tong = 0 
2 
Tài liệu bồi dưỡng học sinh giỏi môn tin THCS – Giải đề thi bằng ngôn ngữ python 
7 
8 
9 
10 
11 
12 
13 
14 
15 
for i in range(1,n+1): 
 tong = tong + 1/(i**2) 
#Xử lý dấu thập phân 
tong = str(round(tong,3)) #làm tròn 3 chữ số thập phân 
tong=tong.replace('.',',',1) #thay dấu chấm . bởi dấu phẩy , 
#Ghi vào file OUT 
fo = open('tong.out','w') 
fo.write(tong) 
fo.close() 
☼Tìm hiểu: .replace(); round(); str() 
Câu 2: Tìm số tự mãn trong dãy 
Qui ước: Số tự mãn bậc 3 là những số bằng tổng lập phương các chữ số 
của nó. Ví dụ: Số 153 là số tự mãn vì 153 = 13 + 53 + 33. 
Cho dãy gồm N phần tử là số nguyên dương A1, A2, ... , An; (0<N<=103; 
0<Ai<=10
6). Viết chương trình tìm những số tự mãn trong dãy số đã cho? 
* Dữ liệu vào từ file: SOTUMAN.INP 
- Dòng đầu tiên chứa số nguyên dương N. 
- Dòng thứ hai chứa N số nguyên dương, các số cách nhau một khoảng trắng. 
* Kết quả ra file: SOTUMAN.OUT 
- Dòng đầu tiên ghi các số tự mãn tìm được theo thứ tự tăng dần, các số cách 
nhau một khoảng trắng. 
Ví dụ: 
SOTUMAN.INP SOTUMAN.OUT 
5 
6 371 18 153 28 
153 371 
Phân tích: Kiểm tra lần lượt các phần tử trong dãy đã cho có là số tự mãn bậc 3 
hay không? Nếu có thì lưu số đó ra một mảng kết quả. 
Thuật toán: xây dựng hàm kiểm tra số tự mãn bậc 3 hoặc tính trực tiếp. 
Code tham khảo: 
Cách 1: Xây dựng hàm kiểm tra số tự mãn 
3 
Tài liệu bồi dưỡng học sinh giỏi môn tin THCS – Giải đề thi bằng ngôn ngữ python 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
#Đọc dữ liệu vào từ file INP 
fi = open('SOTUMAN.INP') 
n = int(fi.readline()) 
a = fi.readline().split() 
for i in range(n): a[i] = int(a[i]) #chuyển mảng a về số nguyên 
fi.close() 
#Xây dựng hàm kiểm tra số tự mãn (True/False) 
def sotuman(m): 
 tlp=0 
 for i in str(m): tlp = tlp + int(i)**3 
 if tlp==m: return True 
 return False 
#Thuật toán xử lý 
b=[] 
for i in a: 
 if sotuman(i): b.append(i) 
b.sort() #Sắp xếp mảng b tăng dần 
#Ghi kết quả vào file OUT 
fo = open('SOTUMAN.OUT','w') 
for i in b: fo.write(str(i)+' ') 
fo.close() 
Cách 2: Tối ưu cách 1 bằng kĩ thuật sử dụng List Comprehension 
1 
2 
3 
4 
5 
6 
7 
#đọc dữ liệu vào 
fi = open('SOTUMAN.INP') 
n = int(fi.readline()) 
a = list(map(int,fi.readline().split())) 
fi.close() 
#Thuật toán với List Comprehension 
b = [] 
4 
Tài liệu bồi dưỡng học sinh giỏi môn tin THCS – Giải đề thi bằng ngôn ngữ python 
8 
9 
10 
11 
12 
13 
14 
for i in a: 
 if i == sum([int(x)**3 for x in str(i)]): b.append(i) 
b.sort() #Sắp xếp mảng b tăng dần 
#ghi file OUT 
fo = open('SOTUMAN.OUT','w') 
for i in b: fo.write(str(i)+' ') 
fo.close() 
☼Tìm hiểu: - Thay 2 dòng lệnh 4, 5 bằng dòng lệnh dùng hàm list(map()): 
a = list(map(int,fi.readline().split())) 
- Bằng kĩ thuật dùng List Comprehension ta sửa lại hàm sotuman(m) của cách 1 
như sau: 
def sotuman(m): 
return m==sum([int(i)**3 for i in str(m)]) 
Câu 3: Xếp hàng 
Trong giờ sinh hoạt tập thể, lớp 9A có n học sinh (n <=45) xếp thành hàng 
dọc. Mỗi học sinh có chiều cao a[i]. Em hãy viết chương trình đếm số bạn có chiều 
cao bằng nhau nhiều nhất. 
* Dữ liệu vào từ file: XEPHANG.INP 
 - Dòng thứ nhất chứa số tự nhiên n. 
 - Dòng thứ hai gồm n số tự nhiên a[i], mỗi số ứng với chiều cao của từng bạn 
(đơn vị cm), các số cách nhau một khoảng trắng. 
 * Kết quả ra file: XEPHANG.OUT 
 - Gồm một dòng ghi 2 số tự nhiên. Số thứ nhất ghi tổng số bạn có chiều cao 
bằng nhau nhiều nhất, số thứ 2 ghi chiều cao tương ứng, các số cách nhau một 
khoảng trắng. 
Ví dụ: 
XEPHANG.INP XEPHANG.OUT 
10 
160 158 158 160 159 158 159 160 158 161 
4 158 
5 
Tài liệu bồi dưỡng học sinh giỏi môn tin THCS – Giải đề thi bằng ngôn ngữ python 
Code tham khảo: 
Cách 1: Lọc phần tử không trùng nhau đôi một bằng List Comprehension 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
fi = open('xephang.inp') 
n = int(fi.readline()) 
a = list(map(int,fi.readline().split())) 
fi.close() 
#Thuật toán 
b=[] 
[b.append(x) for x in a if x not in b] #lọc lấy các số khác nhau trong a 
dem = 0 
chieucao = 0 
for i in b: 
 if dem < a.count(i): 
 dem = a.count(i) 
 chieucao=i 
#ghi file OUT 
fo = open('xephang.out','w') 
fo.write(str(dem)+' ' + str(chieucao)) 
fo.close() 
☼Tìm hiểu: phương thức .count() 
Cách 2: Dùng hàm có sẵn max(set(),key = .count) 
1 
2 
3 
4 
5 
6 
7 
8 
9 
fi = open('xephang.inp') 
n = int(fi.readline()) 
a = list(map(int,fi.readline().split())) 
fi.close() 
#Thuật toán 
chieucao = max(set(a), key = a.count) 
dem=a.count(chieucao) 
#ghi file OUT 
fo = open('xephang.out','w') 
6 
Tài liệu bồi dưỡng học sinh giỏi môn tin THCS – Giải đề thi bằng ngôn ngữ python 
10 
11 
fo.write(str(dem)+' ' + str(chieucao)) 
fo.close() 
☼Tìm hiểu: set(), max(set(), key = .count) 
Câu 4: Kangaroo 
Một chú Kangaroo muốn đi thăm một người bạn trên cùng tuyến đường cách 
đó một khoảng n (đơn vị dm). Kangaroo chỉ có hai cách di chuyển, một là nhảy 
ngắn a (đơn vị dm), hai là nhảy dài b (đơn vị dm). Hỏi chú Kangaroo cần nhảy ít 
nhất bao nhiêu bước nhảy để đến được nhà người bạn (phải nhảy vừa đủ, không nhảy 
quá nhà bạn). 
* Dữ liệu vào từ file: KANGAROO.INP 
- Gồm ba số nguyên dương n, a, b. Các số cách nhau một khoảng trắng (1 <= 
n <= 109, 1 <= a < b <= 20). 
* Kết quả ra file: KANGAROO.OUT 
- Ghi tổng số bước nhảy ít nhất của chú Kangaroo. 
Ví dụ: 
KANGAROO.INP KANGAROO.OUT 
21 2 5 6 
Phân tích: file OUT không nêu ra trường hợp Kangaroo nhảy không được, như vậy 
dữ liệu được cho hoàn toàn phù hợp (chắc chắn có đáp số đúng). 
Lý thuyết số: Nếu gọi x, y lần lượt là số bước nhảy ngắn và số bước nhảy dài thì ta 
sẽ có phương trình nghiệm nguyên: n = ax + by. 
Code tham khảo: 
Cách 1: Dùng khái niệm lát cắt trên iterrator 
1 
2 
3 
4 
5 
6 
7 
#Đọc dữ liệu từ file INP 
fi = open('kangaroo.inp') 
n,a,b = map(int,fi.readline().split()) 
fi.close() 
#Thuật toán với lát cắt trên list 
c = [b]*(n//b) + [a]*(n//a) #khai báo mảng c 
sobuoc = -1 
7 
Tài liệu bồi dưỡng học sinh giỏi môn tin THCS – Giải đề thi bằng ngôn ngữ python 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
for i in range(len(c)-1): 
 for j in range(i+1,len(c)): 
 if sum(c[i:j])==n: 
 sobuoc = len(c[i:j]) 
 break 
 if sobuoc != -1: break 
#Ghi file OUT 
fo = open('kangaroo.out','w') 
fo.write(str(sobuoc)) 
fo.close() 
Cách 2: Áp dụng tính chất chia hết của số nguyên 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
#Đọc dữ liệu từ file INP 
fi = open('kangaroo.inp') 
n,a,b = map(int,fi.readline().split()) 
fi.close() 
#Thuật toán tính chất chia hết số nguyên 
sobuoc=-1 
for i in range(n//b,-1,-1): 
 if (n-i*b)%a==0: 
 sobuoc = i + ((n-i*b)//a) 
 break 
#Ghi file OUT 
fo = open('kangaroo.out','w') 
fo.write(str(sobuoc)) 
fo.close() 
8 
Tài liệu bồi dưỡng học sinh giỏi môn tin THCS – Giải đề thi bằng ngôn ngữ python 
2. ĐỀ THI HSG HUYỆN ĐẠ TẺH – NĂM HỌC 2020 – 2021 
Câu 1: (6 điểm) Ước chung lớn nhất 
 Cho hai số tự nhiên N, M (1 < N, M < 109). Viết chương trình tìm ước chung lớn 
nhất của hai số N và M? 
 Dữ liệu vào từ file: UCLN.INP 
 - Dòng đầu tiên ghi hai số N và M, cách nhau một khoảng trắng. 
Kết quả ra file: UCLN.OUT 
 - Dòng đầu tiên ghi ước chung lớn nhất tìm được. 
 Ví dụ: 
UCLN.INP UCLN.OUT 
2 4 2 
11 17 1 
Phân tích: 
Code tham khảo: 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
#Đọc file INP 
fi = open('UCLN.INP') 
n,m = map(int,fi.readline().split()) 
fi.close() 
#Hàm tìm UCLN 
def ucln(a,b): 
 while a!=b: 
 if a > b: a = a - b 
 else: b = b - a 
 return a 
#ghi file OUT 
fo = open('UCLN.OUT','w') 
print(ucln(m,n),file=fo) 
fo.close() 
9 
Tài liệu bồi dưỡng học sinh giỏi môn tin THCS – Giải đề thi bằng ngôn ngữ python 
Câu 2: (7 điểm) Đếm các số nguyên tố 
 Cho dãy số nguyên gồm N phần tử Ai (0 < N < 103, 0 < Ai < 106). Viết chương 
trình đếm xem trong dãy số đã cho có bao nhiêu phần tử là số nguyên tố? 
 Dữ liệu vào từ file: NGUYENTO.INP 
 - Dòng đầu tiên ghi hai số N 
- Dòng thứ hai ghi N số nguyên, các số cách nhau một khoảng trắng. 
Kết quả ra file: NGUYENTO.OUT 
 - Dòng đầu tiên ghi kết quả đếm được. 
 Ví dụ: 
NGUYENTO.INP NGUYENTO.OUT 
2 
2 4 
1 
5 
7 13 27 13 29 
4 
Phân tích: 
Code tham khảo: 
Cách 1: Dùng thuật toán tìm kiếm trên dãy số 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
# Ham kiem tra so nguyen to 
def ktnt(a): 
 if(a<2): return False 
 for i in range(2,a//2+1): 
 if a%i==0: return False 
 return True 
#đọc file INP 
fi = open('NGUYENTO.INP') 
n = int(fi.readline()) 
dayso = list(map(int,fi.readline().split())) 
fi.close() 
#Thuật toán tìm kiếm 
10 
Tài liệu bồi dưỡng học sinh giỏi môn tin THCS – Giải đề thi bằng ngôn ngữ python 
13 
14 
15 
16 
17 
18 
19 
dem=0 
for i in dayso: 
 if ktnt(i): dem += 1 
#ghi file out 
fo = open('NGUYENTO.OUT','w') 
fo.write(str(dem)) 
fo.close() 
☼Tìm hiểu: Với cách viết câu lệnh dòng 14, 15 thì n được cho không dùng đến. 
Cách 2: Dùng List Comprehension 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
# Ham kiem tra so nguyen to trong python 
def ktnt(a): 
 if(a<2): return False 
 for i in range(2,a//2+1): 
 if a%i==0: return False 
 return True 
#đọc file INP 
fi = open('NGUYENTO.INP') 
n = int(fi.readline()) 
dayso = list(map(int,fi.readline().split())) 
fi.close() 
# thuật toán 
b = [x for x in dayso if ktnt(x)] 
#ghi file out 
fo = open('NGUYENTO.OUT','w') 
fo.write(str(len(b))) 
fo.close() 
☼Tìm hiểu: hàm len() 
Câu 3: (7 điểm) Dãy theo quy luật 
Quy ước: Ứng với mỗi số tự nhiên x (0 < x < 106), ta có số tự nhiên f(x) bằng 
tổng bình phương các chữ số của x. 
11 
Tài liệu bồi dưỡng học sinh giỏi môn tin THCS – Giải đề thi bằng ngôn ngữ python 
Chẳng hạn: x = 12 thì f(x) = 12 + 22 = 5. 
Từ x ta xây dựng dãy Xn theo quy ước như sau: 
 X1 = x ; X2 = f(X1) ; X3 = f(X2) ; ; Xi = f(Xi - 1) (với 1 <= i <= n < 102) 
Viết chương trình in ra dãy (Xn)? 
Dữ liệu vào từ file: DAYXN.INP 
- Dòng đầu tiên ghi số tự nhiên x và n, cách nhau một khoảng trắng. 
Kết quả ra file: DAYXN. OUT 
- Dòng đầu tiên ghi n phần tử đầu tiên của dãy, các số cách nhau một khoảng 
trắng. 
Ví dụ: 
DAYXN.INP DAYXN. OUT 
12 4 12 5 25 29 
Phân tích: 
Code tham khảo: 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
#Hàm tính tổng bình phương các chữ số 
def f(x): 
 return sum([int(i)**2 for i in str(x)]) 
#Đọc file INP 
fi=open('DAYXN.INP') 
x,n=map(int,fi.readline().split()) 
fi.close() 
#Thuật toán_Ghi file OUT 
fo=open('DAYXN.OUT','w') 
for i in range(n): 
 fo.write(str(x)+' ') 
 x=f(x) 
fo.close() 
☼Tìm hiểu: 
12 
Tài liệu bồi dưỡng học sinh giỏi môn tin THCS – Giải đề thi bằng ngôn ngữ python 
3. ĐỀ THI HSG HUYỆN ĐẠ HOAI – NĂM HỌC 2020 – 2021 
Câu 1: (5 điểm) Tính tổng 
 Viết chương trình tính và xuất ra màn hình tổng sau: 
1 1 1 1
S= + + ...+
1.3 2.4 3.5 .( 2)a a
+
+
 Với a là số nguyên dương nhập từ bàn phím. Kết quả làm tròn 1 chữ số thập 
phân. 
 Ví dụ: 
Dữ liệu vào (a) Kết quả 
1 0.3 
2 0.5 
Phân tích: Bài này đề yêu cầu nhập/xuất chuẩn, không yêu cầu dữ liệu vào ra từ 
file. 
Code tham khảo: 
1 
2 
3 
4 
a = int(input('- Nhập a = ')) 
s = 0 
for i in range(1,a+1): s += 1/(i*(i+2)) 
print('%.1f'%s) 
☼Tìm hiểu: - Định dạng số thập phân trong python theo chuẩn '%.1f'% 
- Khi a là số lớn (từ 7 chữ số trở lên) thì thời gian chạy của vòng lặp (for, while) là 
rất lâu, đây được xem là một bài tập có “bẫy” về thời gian chạy và kiến thức toán 
học. 
Kiến thức số học: Các tổng mà mỗi số hạng có tử số nhỏ hơn mẫu số (hay số hạng 
của tổng nhỏ hơn 1) thì tổng đó sẽ hội tụ về gần một giá trị cố định nào đó. Trong 
câu trên, với a>=10 thì S làm tròn 1 chữ số thập phân sẽ luôn bằng 0.7; Do vậy, để 
tránh “bẩy” thời gian chạy với số lớn ta sửa lại đoạn code như sau: 
1 
2 
3 
a = int(input('- Nhập a = ')) 
if a>=10: s = 0.7 
else: 
13 
Tài liệu bồi dưỡng học sinh giỏi môn tin THCS – Giải đề thi bằng ngôn ngữ python 
4 
5 
 for i in range(1,a+1): s += 1/(i*(i+2)) 
print('%.1f'%s) 
Câu 2: (5 điểm) Tổng chẵn 
 Cho một dãy số nguyên có n số (0<n<10000). Viết chương trình xuất ra các 
số chẵn có trong dãy và tổng các chữ số chẵn đó. 
* Dữ liệu vào từ file: TONGCHAN.INP 
- Dòng 1: Ghi số tữ nhiên n. 
- Dòng 2: Ghi n số nguyên của dãy, mỗi số cách nhau một khoảng trắng. 
* Kết quả ra file: TONGCHAN.OUT 
- Dòng 1: Ghi các số chẵn có trong dãy, các số cách nhau một khoảng trắng. 
- Dòng 2: Ghi tổng các số chẵn có trong dãy. 
Ví dụ: 
TONGCHAN.INP TONGCHAN. OUT 
5 
2 3 6 8 7 
2 6 8 
16 
7 
8 9 6 12 20 25 45 
8 6 12 20 
46 
Phân tích: 
Code tham khảo: 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
#Đọc dữ liệu từ file INP 
fi=open('TONGCHAN.INP') 
n=int(fi.readline()) 
a=list(map(int,fi.readline().split())) 
fi.close() 
#Thuật toán tìm kiếm, tính tổng và ghi file OUT 
fo=open('TONGCHAN.OUT','w') 
s=0 
for i in a: 
 if i%2==0: 
14 
Tài liệu bồi dưỡng học sinh giỏi môn tin THCS – Giải đề thi bằng ngôn ngữ python 
11 
12 
13 
14 
15 
 fo.write(str(i)+' ') 
 s=s+i 
fo.write('\n') 
fo.write(str(s)) 
fo.close() 
 Có thể dùng List Comprehension để thay thế đoạn code từ dòng 8 đến dòng 
12 như sau: 
b = [x for x in a if x%2==0] 
for i in b: fo.write(str(i)+' ') 
fo.write('\n') 
fo.write(str(sum(b))) 
Câu 3: (5 điểm) Số thân thiện 
 Số nguyên tố là số lớn hơn 1 và chỉ chia hết cho 1 và chính nó. Hai số tự nhiên 
được gọi là cặp số thân thiện với nhau nếu có chung ước nguyên tố lớn nhất. 
 Ví dụ số 14 và 21 là hai số thân thiện với nhau vì cùng có ước nguyên tố lớn 
nhất là 7. 
 Viết chương trình tìm 5 số thân thiện với số tự nhiên a (1<a<105). 
 * Dữ liệu vào từ file: THANTHIEN.INP 
- Dòng 1: Ghi số tự nhiên a. 
Kết quả ra file: THANTHIEN.OUT 
- Dòng 1: Ghi 5 số thân thiện của số a, các số cách nhau một khoảng trắng. 
Ví dụ: 
THANTHIEN.INP THANTHIEN.OUT 
25 5 10 15 20 25 
14 7 14 21 28 35 
Phân tích: 
 -“Hai số tự nhiên được gọi là cặp số thân thiện với nhau nếu có chung ước 
nguyên tố lớn nhất” hiểu đây là một quy ước, không phải là khái niệm của lý thuyết 
số. 
15 
Tài liệu bồi dưỡng học sinh giỏi môn tin THCS – Giải đề thi bằng ngôn ngữ python 
- Qua 2 ví dụ ta thấy kết quả file OUT là ghi 5 số thân thiện từ bé đến lớn bao 
gồm cả chính số. Thoạt nhìn có vẻ rất đơn giản! Nhưng bài toán này được xem là 
một dạng “bẩy” về kiến thức toán học! 
Chúng ta sẽ phân tích và tìm vấn đề nhé! 
Dựa vào quy ước và file OUT, ta dễ dàng xây dựng thuật toán chỉ đơn giản 
như sau: tìm ước nguyên tố lớn nhất của a, sau đó ghi vào file OUT lần lượt tích của 
ước nguyên tố lớn nhất với các số từ 1 đến 5. Như đoạn code dưới đây! 
Code tham khảo: 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
#Hàm kiểm tra số nguyên tố 
def ktnt(n): 
 if n<2: return False 
 for i in range(2,n//2+1): 
 if n%i==0: return False 
 return True 
#Đọc dữ liệu file INP 
fi=open('THANTHIEN.INP') 
a=int(fi.readline()) 
fi.close() 
#Tìm ước nguyên tố lớn nhất của a 
unt = 1 
for i in range(a,1,-1): 
 if a%i==0 and ktnt(i): unt=i;break 
#Ghi file OUT 
fo=open('THANTHIEN.OUT','w') 
for i in range(1,6): fo.write(str(i*unt)+' ') 
fo.close() 
Bây giờ ta xét với bộ dữ liệu: 
THANTHIEN.INP THANTHIEN.OUT 
2 2 4 6 8 10 
16 
Tài liệu bồi dưỡng học sinh giỏi môn tin THCS – Giải đề thi bằng ngôn ngữ python 
Ta thấy, số 6 và 10 có ước nguyên tố lớn nhất là 3 và 5; như vậy số 6, 10 và 2 
không phải là cặp số thân thiết theo quy ước. Hay nói cách khác thì bộ dữ liệu được 
tạo ra từ code trên là sai. 
 Bây giờ ta cải tiến lại code như sau: 
Cách 1: Kĩ thuật tìm kiếm với hàm tự tạo 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
#Hàm kiểm tra số nguyên tố 
def ktnt(n): 
 if n<2: return False 
 for i in range(2,n//2+1): 
 if n%i==0: return False 
 return True 
#Hàm tìm ước nguyên tố lớn nhất của một số 
def uocnt(n): 
 if ktnt(n): return n 
 for i in range(n//2+1,1,-1): 
 if n%i==0 and ktnt(i): return i 
#Đọc dữ liệu file INP 
fi=open('THANTHIEN.INP') 
a=int(fi.readline()) 
fi.close() 
#Tìm ước nguyên tố lớn nhất của a 
unt = uocnt(a) 
dem=1 
i = 1 
#Ghi file OUT 
fo=open('THANTHIEN.OUT','w') 
fo.write(str(unt)+' ') 
while dem<5: 
 i = i + 1 
 if uocnt(unt*i)==unt: 
17 
Tài liệu bồi dưỡng học sinh giỏi môn tin THCS – Giải đề thi bằng ngôn ngữ python 
26 
27 
28 
 fo.write(str(unt*i)+' ') 
 dem = dem + 1 
fo.close() 
Bây giờ ta kiểm chứng lại với các bộ dữ liệu: 
THANTHIEN.INP THANTHIEN.OUT 
25 5 10 15 20 25 
14 7 14 21 28 35 
2 2 4 8 16 32 
 Cách 2: Cải tiến thuật toán với List Comprehension 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
#Hàm kiểm tra số nguyên tố 
def ktnt(n): 
 if n<2: return False 
 for i in range(2,n//2+1): 
 if n%i==0: return False 
 return True 
#Hàm tìm ước nguyên tố lớn nhất của một số 
def uocnt(n): 
 if ktnt(n): return n 
 for i in range(n//2+1,1,-1): 
 if n%i==0 and ktnt(i): return i 
#Đọc dữ liệu file INP 
fi=open('THANTHIEN.INP') 
a=int(fi.readline()) 
fi.close() 
#Tìm ước nguyên tố lớn nhất của a 
unt = uocnt(a) 
b=[] 
[b.append(unt*i) for i in range(100) if (uocnt(unt*i)==unt) and len(b)<5] 
#Ghi file OUT 
18 
Tài liệu bồi dưỡng học sinh giỏi môn tin THCS – Giải đề thi bằng ngôn ngữ python 
21 
22 
23 
24 
fo=open('THANTHIEN.OUT','w') 
for i in b: 
 fo.write(str(i)+' ' ) 
fo.close() 
Bài 4: (5.0 điểm) Phần tử yên ngựa 
Một bảng A gồm m hàng và n cột được gọi là một ma trận m×n (m≠0, n≠0). 
Phần tử tại hàng thứ i cột thứ j được ký hiệu là A[i,j] hoặc A[i][j]. Phần tử A[i,j] 
được gọi là phần tử yên ngựa nếu nó bé nhất trong hàng i và lớn nhất trong cột j. 
Viết chương trình các tìm phần tử yên ngựa (nếu có) của ma trận A có m hàng 
n cột. 
* Dữ liệu vào từ file: PTYN.INP 
- Dòng đầu ghi hai số tự nhiên m, n, mỗi số cách nhau 1 khoảng trắng. 
- m dòng tiếp theo, mỗi dòng ghi n số nguyên là các phần tử của ma trận ma trận 
A, mỗi số cách nhau 1 khoảng trắng. 
Dữ liệu ghi ra file: PTYN.OUT 
- Ghi các cặp số (i,j) là chỉ số hàng, cột của phần tử A[i,j] nếu A[i,j] là phần tử 
yên ngựa. Mỗi cặp số ghi trên một dòng. Nếu không có phần tử yên ngựa thì ghi 
“khong co”. 
Ví dụ: 
PTYN.INP PTYN.OUT 
3 3 
1 2 3 
4 5 6 
7 8 9 
(3,1) 
3 3 
15 10 5 
55 4 6 
76 1 2 
khong co 
19 
Tài liệu bồi dưỡng học sinh giỏi môn tin THCS – Giải đề thi bằng ngôn ngữ python 
Phân tích: 
Code tham khảo: 
Cách 1: Tìm kiếm trên ma trận 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
#Đọc dữ liệu từ file INP 
fi=open('PTYN.INP') 
m,n=map(int,fi.readline().split())#m = hàng, n = cột 
a=[] 
for i in fi: a.append(list(map(int,i.split()))) 
fi.close() 
#lấy min hàng đưa vào mảng 1 chiều 
min_h=[0]*m 
for j,i in enumerate(a): 
 min_h[j] = min(i) 
#lấy max cột đưa vào mảng 1 chiều 
max_c=[0]*n 
for i in range(n): 
 cot=[0]*n 
 for j in range(m): 
 cot[j] = a[j][i] 
 max_c[i]=max(cot) 
#duyệt so sánh, nếu min_h[i]==max_c[j] thì xuất i+1,j+1 
fo=open('PTYN.OUT','w') 
kt = False 
for i in range(m): #min_h 
 for j in range(n): #max_c 
 if min_h[i]==max_c[j]: 
 fo.write('('+str(i+1)+','+str(j+1)+')\n') 
 kt = True 
#trường hợp không có 
if not kt: fo.write('khong co') 
20 
Tài liệu bồi dưỡng học sinh giỏi môn tin THCS – Giải đề thi bằng ngôn ngữ python 
28 fo.close() 
☼Tìm hiểu: - Hàm enumerate() 
 - Đọc ma trận vào mảng a và chuyển các phần tử thành int: 
a=[] 
for i in fi: a.append(list(map(int,i.split()))) 
Cách 2: Cải tiến cách 1 bằng kĩ thuật List Comprehension 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
#Đọc dữ liệu từ file INP 
fi=open('PTYN.INP') 
m,n=map(int,fi.readline().split())#m = hàng, n = cột 
a=[] 
for i in fi: a.append(list(map(int,i.split()))) 
fi.close() 
#lấy min hàng đưa vào mảng 1 chiều 
min_h=[min(i) for i in a] 
#lấy max cột đưa vào mảng 1 chiều 
_a=[list(i) for i in zip(*a)] #chuyển vị ma trận a thành _a 
max_c=[max(i) for i in _a] 
#duyệt so sánh, nếu min_h[i]==max_c[j] thì xuất i+1,j+1 
fo=open('PTYN.OUT','w') 
kt = False 
for i in range(m): #min_h 
 for j in range(n): #max_c 
 if min_h[i]==max_c[j]: 
 fo.write('('+str(i+1)+','+str(j+1)+')\n') 
 kt = True 
#trường hợp không có 
if not kt: fo.write('khong co') 
fo.close() 
☼Tìm hiểu: - hàm zip(*a) 
21 
Tài liệu bồi dưỡng học sinh giỏi môn tin THCS – Giải đề thi bằng ngôn ngữ python 
4. ĐỀ THI HSG HUYỆN BẢO LỘC – NĂM HỌC 2020 – 2021 
Câu 1: (5 điểm) Tính tổng 
 Cho ba số nguyên dương A, B và K (0 < A < B < 106, 1 < K < 103). Viết 
chương trình tính tổng tất cả các số M (A < M < B), sao cho M chia hết cho K. 
 Dữ liệu vào từ file: TONG.INP 
 - Dòng đầu tiên ghi ba số nguyên A, B và K, cách nhau một khoảng trắng. 
 Kết quả ra file: TONG.OUT 
 - Dòng đầu tiên ghi kết quả tính được. 
 Ví dụ: 
TONG.INP TONG.OUT 
2 8 2 10 
3 4 3 0 
Phân tích: 
Code tham khảo: 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
#Đọc dữ liệu từ file INP 
fi = open('TONG.INP') 
a,b,k=map(int,fi.readline().split()) 
fi.close() 
#Thuật toán 
tong=0 
for m in range(a+1,b): 
 if m%k==0: tong = tong+m 
#Ghi file OUT 
fo = open('TONG.OUT','w') 
fo.write(str(tong)) 
fo.close() 
☼Tìm hiểu: 
Cải tiến cách 1 bằng kĩ thuật List Comprehension, bằng cách thay các dòng 
lệnh 6, 7, 8 bằng dòng lệnh sau: 
22 
Tài liệu bồi dưỡng học sinh giỏi môn tin THCS – Giải đề thi bằng ngôn ngữ python 
tong = sum([x for x in range(a+1,b) if x%k==0]) 
Câu 2: (5 điểm) Tìm số đường khép kín 
 Ta qui ước: 
+ Các chữ số: 1, 2, 3, 5, 7 có 0 đường khép kín. 
 + Các chữ số: 0, 4, 6, 9 có 1 đường khép kín; 
+ Chữ số: 8 có 2 đường khép kín; 
 Viết chương trình tính tổng số đường khép kín của một số nguyên dương N 
(N <1010). 
 Dữ liệu vào từ file: KHEPKIN.INP 
 - Dòng đầu tiên ghi số N. 
 Kết quả ra file: KHEPKIN.OUT 
 - Dòng đầu tiên ghi tổng số đường khép kín tính được. 
 Ví dụ: 
KHEPKIN.INP KHEPKIN.OUT 
2369524 3 
Phân tích: 
Code tham khảo: 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
#Đọc dữ liệu từ file INP 
fi = open('KHEPKIN.INP') 
n = int(fi.read()) 
fi.close() 
#Thuật toán 
dkk = 0 
for i in str(n): 
 if i in '0469': dkk = dkk + 1 
 elif i=='8': dkk = dkk + 2 
#Ghi file OUT 
fo = open('KHEPKIN.OUT','w') 
fo.write(str(dkk)) 
fo.close() 
23 
Tài liệu bồi dưỡng học sinh giỏi môn tin THCS – Giải đề thi bằng ngôn ngữ python 
☼ Tìm hiểu: 
Câu 3: (5 điểm) Xóa ký tự trong xâu 
Cho xâu có N ký tự chữ số (0 < N < 255). Viết chương trình xóa đi K ký tự 
(0 < K < N) để xâu còn lại biểu diễn một số bé nhất. 
Dữ liệu vào từ file: XAU.INP 
- Dòng đầu tiên chứa xâu có N ký tự chữ số, các ký tự chữ số viết liền nhau. 
- Dòng thứ hai chứa số K. 
Kết quả ra file: XAU.OUT 
- Dòng đầu tiên ghi xâu ký tự tìm được theo yêu cầu. 
Ví dụ: 
XAU.INP XAU.OUT 
65278934 
3 
27834 
Phân tích: 
Code tham khảo: 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
fi = open('XAU.INP') 
s = list(fi.readline()) 
k = int(fi.readline()) 
fi.close() 
#Thuật toán 
for i in range(k): 
 j=0 
 while (j<len(s)) and (s[j]<=s[j+1]): j += 1 
 del(s[j]) 
#Ghi file OUT 
fo = open('XAU.OUT','w') 
fo.write(''.join(s)) 
fo.close() 
☼ Tìm hiểu: 
- Hàm del(), ''.join() 
24 
Tài liệu bồi dưỡng học sinh giỏi môn tin THCS – Giải đề thi bằng ngôn ngữ python 
- Trong đề bài cho “xâu có N ký tự chữ số” nhưng tại dòng lệnh 2: 
s=list(fi.readline()) là đọc từng chữ số và gán vào một mảng một chiều s, thay vì 
lệnh đọc s=fi.readline(). Vì trong NNLT python qui định chuỗi str là dữ liệu có tính 
“bất biến”, do vậy không có hàm hay phương thức nào cho phép xóa một ký tự bất 
kỳ trong chuỗi s. Vì vậy, ta phải đọc vào mảng một chiều s để áp dụng hàm del(). 
- Tại dòng lệnh 8: while (j<len(s)) and (s[j]<=s[j+1]): j += 1 nếu thay đổi dấu 
“ =” thì bài toán trở thành là tìm “số lớn nhất”. 
Câu 4: (5 điểm) Bộ ba số 
Cho dãy N (1 <= N <= 103) số nguyên dương A1, A2, ..., AN (Ai <= 103). Với 
bộ ba chỉ số i, j và k (1 <= i < j < k <= N), hãy tìm giá trị S = 2Ai – 3Aj + 5Ak sao 
cho S đạt giá trị lớn nhất. 
Dữ liệu vào từ file: BOBASO.INP 
- Dòng đầu tiên chứa số N 
- Dòng thứ hai chứa N số nguyên dương A1, A2, ..., AN; các số cách nhau một 
khoảng trắng. 
Kết quả ra file: BOBASO.OUT 
- Dòng đầu tiên ghi giá trị của S tìm được. 
Ví dụ: 
BOBASO.INP BOBASO.OUT 
3 
3 2 1 
5 
7 
3 5 2 6 4 5 7 
39 
Phân tích: 
Code tham khảo: 
1 
2 
3 
4 
#Đọc dữ liệu từ file INP 
fi=open('BOBASO.INP') 
n=int(fi.readline()) 
a=list(map(int,fi.readline().split())) 
25 
Tài liệu bồi dưỡng học sinh giỏi môn tin THCS – Giải đề thi bằng ngôn ngữ python 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
fi.close() 
#Thuật toán 
s=0 
for i in range(0,n-2): 
 for j in range(i+1,n-1): 
 for z in range(j+1,n): 
 if 2*a[i]-3*a[j]+5*a[z]>s: s=2*a[i]-3*a[j]+5*a[z] 
#Ghi file OUT 
fo=open('BOBASO.OUT','w') 
fo.write(str(s)) 
fo.close() 
☼ Tìm hiểu: 
5. ĐỀ THI HSG HUYỆN BẢO LÂM – NĂM HỌC 2020 – 2021 
Câu 1: (6 điểm) Diện tích tam giác vuông 
 Cho ba số tự nhiên a, b, c (0 < a, b, c < 106). Hãy viết chương tính diện tích 
tam giác nếu ba số đã cho là số đo ba cạnh của một tam giác vuông. 
 Dữ liệu vào từ file: TAMGIAC.INP 
 - Dòng đầu tiên ghi ba số tự nhiên a, b và c, các số cách nhau khoảng trắng. 
 Kết quả ra file: TAMGIAC.OUT 
 - Dòng đầu tiên ghi diện tích tính được (làm tròn một chữ số thập phân), nếu 
nếu ba số đã cho không phải là ba cạnh của tam giác vuông thì ghi số -1. 
 Ví dụ: 
TAMGIAC.INP TAMGIAC.OUT 
3 4 5 6.0 
3 4 9 -1 
Phân tích: 
Code tham khảo: 
1 
2 
#Đọc dữ liệu từ file INP 
fi = open('TAMGIAC.INP') 
26 
Tài liệu bồi dưỡng học sinh giỏi môn tin THCS – Giải đề thi bằng ngôn ngữ python 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
a,b,c = map(int,fi.readline().split()) 
fi.close() 
#Thuật toán 
s = -1 
if a*a == b*b + c*c: s = round(0.5*b*c,1) 
elif b*b == a*a + c*c: s = round(0.5*a*c,1) 
elif c*c == b*b + a*a: s= round(0.5*a*b,1) 
#Ghi file OUT 
fo = open('TAMGIAC.OUT','w') 
fo.write(str(s)) 
fo.close() 
Cải tiến code trên bằng cách sử dụng mảng một chiều như sau: 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
#Đọc dữ liệu từ file INP 
fi = open('TAMGIAC.INP') 
a = list(map(int,fi.readline().split())) 
fi.close() 
#Thuật toán 
a.sort() 
s = -1 
if a[2]**2 == a[0]**2 + a[1]**2: s = round(0.5*a[0]*a[1],1) 
#Ghi file OUT 
fo = open('TAMGIAC.OUT','w') 
fo.write(str(s)) 
fo.close() 
☼ Tìm hiểu: 
Câu 2: (7 điểm) Tính số ngày 
Với lịch dương thì các tháng có 31 ngày là: 1, 3, 5, 7, 8, 10, 12 và các tháng 
có 30 ngày là: 4, 6, 9, 11. Riêng tháng 2 có thể có 28 hoặc 29 ngày tùy theo năm. Từ 
năm 2012 đến năm 2099, các năm chia hết cho 4 đều là năm nhuận và tháng 2 của 
năm nhuận có thêm ngày thứ 29. 
27 
Tài liệu bồi dưỡng học sinh giỏi môn tin THCS – Giải đề thi bằng ngôn ngữ python 
Cho hai bộ ba số {d1, m1, y1} và {d2, m2, y2}, mỗi bộ ba số là lần lượt là 
ngày, tháng, năm (2012 <= y1, y2 <=2099). Hãy viết chương trình tính số ngày trong 
khoảng thời gian được cho. 
 Dữ liệu vào từ file: SONGAY.INP 
 - Hai dòng đầu, mỗi dòng ghi lần lượt ba số là ngày, tháng và năm, các số 
cách nhau khoảng trắng. 
 Kết quả ra file: SONGAY.OUT 
 - Dòng đầu tiên ghi số ngày tính được. 
 Ví dụ: 
SONGAY.INP SONGAY.OUT 
25 1 2012 
26 3 2012 
61 
20 1 2018 
20 11 2020 
1035 
Phân tích: 
Code tham khảo: 
Cách 1: Dựa theo cách tính toán số học (phép đếm) 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
#Đọc dữ liệu vào từ file INP 
fi = open('SONGAY.INP') 
d1,m1,y1 = map(int,fi.readline().split()) 
d2,m2,y2 = map(int,fi.readline().split()) 
fi.close() 
#Thuật toán 
a=[0,31,28,31,30,31,30,31,31,30,31,30,31] 
songay=0 
if y1==y2: 
 if y1%4==0: a[2] = 29 
 a[m1] = a[m1] - d1 
 a[m2] = d2 
28 
Tài liệu bồi dưỡng học sinh giỏi môn tin THCS – Giải đề thi bằng ngôn ngữ python 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
 if m2==m1: songay = d2 - d1 
 else: songay = sum(a[m1:m2+1]) 
elif y1<y2: 
 #(1) Tính số ngày từ d1/m1 đến cuối năm y1 
 if y1%4==0: a[2] = 29 
 a[m1] = a[m1] - d1 
 songay=sum(a[m1:]) 
 #(2) Tính số ngày từ đầu năm y2 đến d1/m1 đến cuối năm y1 
 a=[0,31,28,31,30,31,30,31,31,30,31,30,31] 
 if y2%4==0: a[2] = 29 
 else: a[2] = 

Tài liệu đính kèm:

  • pdftai_lieu_boi_duong_hoc_sinh_gioi_tin_hoc_bac_thcs_chuyen_de.pdf