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.
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:
- tai_lieu_boi_duong_hoc_sinh_gioi_tin_hoc_bac_thcs_chuyen_de.pdf