1. Trang chủ
  2. » Giáo án - Bài giảng

Bài giải Đề thi Tin học trẻ THCS các quận,huyện,thị xã ■ Lập trình Free Pascal ■ Tập 2

34 1,6K 23

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 34
Dung lượng 1,35 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Bài giải tham khảo Đề thi Tin học trẻ tỉnh Lâm Đồng năm 2018 ■ Bài giải tham khảo Đề thi Tin học trẻ tỉnh Bắc Giang năm 2019 ■ Bài giải tham khảo Đề thi Tin học trẻ tỉnh Ninh Bình 2019 ■ Bài giải tham khảo Đề thi Tin học trẻ tỉnh Lâm Đồng năm 2019 ■ Bài giải tham khảo Đề thi Tin học trẻ huyện Vũ Quang năm 2019■ Bài giải tham khảo Đề thi Tin học trẻ tỉnh Gia Lai năm 2019

Trang 1

Đề thi Tin học trẻ tỉnh Lâm Đồng năm 2018

Khối Trung học Cơ sở Thời gian làm bài: 150 phút

Hướng giải quyết:

- Dùng kỹ thuật tách số: Muốn tách số 234 thành số 2, 3 và 4 chúng ta thực hiện như sau:

2 3 mod 10 (phép chia lấy số dư, 234 / 10 =23 dư 4) = 4

23 4 div 10 (phép chia bỏ số lẻ: 234 / 10 =23.4, bỏ số lẻ thành 23) = 23

 Thực hiện tiếp tục 2 thao tác trên chúng ta thu được thêm số 3 và số 2

- Sau khi tính tổng bình phương các chữ số của 234 (22 + 32 + 42 = 4 + 9 + 16 = 29) = 29,

ta xét nếu số 29 là số nguyên tố thì 234 là “số đẹp”

- Tạo hàm xét số k có phải là “số đẹp” hay không dựa theo kỹ thuật tách số như trên

- Tạo hàm xét số k có phải là số nguyên tố hay không:

Trang 2

- Tạo biến số so xuất phát từ 11 (so <=10 chắc chắn không phải là số đẹp), biến đếm

dem xuất phát từ 0 Xét nếu so là “số đẹp” thì tăng biến dem đến khi nào = n thì ngưng

Lập trình như sau:

Var

n, Dem, So: LongInt;

{ -} Function NT(k: LongInt): Boolean;

Var i: LongInt;

Begin

If k<2 then Exit(False);

For i:=2 to Trunc(SQRT(k)) do

If k mod i=0 then Exit(False);

Exit(True);

End;

{ -} Function SoDep(k: LongInt): Boolean;

Var Tong_BP: LongInt;

While Dem<n do Begin

If SoDep(So) then Inc(Dem);

Trang 3

Hướng giải quyết:

- Muốn số người đi thang máy là nhiều nhất thì phải chọn những người nhẹ nhất

- Sắp thứ tự mảng một chiều A chứa trọng lượng của những người cần đi thang máy tăng dần, chú ý lưu trữ thứ tự của những người này vào mảng TT khi nhập từ file input và giữ thứ tự này trong quá trình sắp xếp trọng lượng

- Chọn người sau khi đã sắp xếp theo trọng lượng trong khi tổng trọng lượng <= tải trọng của thang máy thì ngưng, đánh dấu vào mảng DD

- Duyệt lại mảng A, chỉ in ra các A[i] đã được đánh dấu trong mảng DD (DD[i]=True)

Lập trình như sau:

Var

a, b, TT: Array [1 20] of Integer; // Tối đa 20 người/ thang máy

DD: Array [1 20] of Boolean; // Mảng đánh dấu

While not EOF() do Begin

Read(a[i]); b[i]:=a[i]; // Lưu lại mảng A vào mảng B

TT[i]:=i; // Ghi thứ tự

Inc(i);

End;

Trang 4

// Sắp thứ tự theo trọng lượng

For i:=1 to n-1 do

For j:=i+1 to n do

If a[i]>a[j] then Begin

t:=a[i]; a[i]:=a[j]; a[j]:=t;

t:=TT[i]; TT[i]:=TT[j]; TT[j]:=t; // Thứ tự cũng phải đảo theo

Trang 5

Hướng giải quyết:

- Đánh dấu toàn bộ các ô là chưa duyệt (toàn bộ mảng đánh dấu DD có giá trị False)

- Dùng thuật toán vết dầu loang (đệ quy) để đi qua các ô có cùng giá trị 0 hay 1:

Trang 6

 Nếu dòng >1 và ô trên (dòng hiện thời - 1) có cùng giá trị 0 hay 1 và ô trên chưa duyệt qua thì duyệt ô này

 Nếu dòng <n và ô dưới (dòng hiện thời + 1) có cùng giá trị 0 hay 1 và ô dưới chưa duyệt qua thì duyệt ô này

 Nếu cột >1 và ô trái (cột hiện thời - 1) có cùng giá trị 0 hay 1 và ô trái chưa duyệt qua thì duyệt ô này

 Nếu cột < m và ô phải (cột hiện thời + 1) có cùng giá trị 0 hay 1 và ô phải chưa duyệt qua thì duyệt ô này

Lập trình như sau:

Var

n, m, i, j, x1, y1, x2, y2: Integer;

a: Array [1 100, 1 100] of Integer; // Đề thi không có giới hạn n,m

DD: Array [1 100, 1 100] of Boolean; // Mảng đánh dấu đã duyệt qua

CungMien: Boolean; // Cùng miền 0 hay miền 1 là True, ngược lại là False

{ -} Procedure Loang(d, c, v01: Integer); // Loang dòng, cột, giá trị ô 0 hay 1

Begin

DD[d, c]:=True;

If (d=x2) and (c=y2) then Begin CungMien:=True; Exit; End; // Ô đích

If (d>1) and (a[d-1,c]=v01) and (DD[d-1,c]=False) then Loang(d-1,c,v01);

If (d<n) and (a[d+1,c]=v01) and (DD[d+1,c]=False) then Loang(d+1,c,v01);

If (c>1) and (a[d,c-1]=v01) and (DD[d,c-1]=False) then Loang(d,c-1,v01);

If (c<m) and (a[d,c+1]=v01) and (DD[d,c+1]=False) then Loang(d,c+1,v01); End;

{====================================================================} Begin

While not EOF() do Begin

ReadLn(x1, y1, x2, y2);

FillChar(DD, sizeOf(DD), False);

CungMien:=False;

If a[x1, y1]=0 then Loang(x1, y1, 0)

else Loang(x1, y1, 1);

If CungMien then WriteLn(1) else WriteLn(2);

End;

Close(Input);

Close(Output);

End

Trang 7

Đề thi Tin học trẻ tỉnh Bắc Giang năm 2019

Khối Trung học Cơ sở Thời gian làm bài: 120 phút

Hướng giải quyết:

- Tách nhóm 2 số: ví dụ số 30 25

 Lấy mod 100 (chia 100 lấy số dư) để được 2 số cuối: 3025 mod 100 = 25

 Div 100 (chia 100 lấy kết quả sau đó bỏ số lẻ): 3025 div 100 = 30

- Chạy vòng lặp For i:=1000 đến 9999 (mỗi số i có 4 chữ số)

 Tách 2 số đầu sd và 2 số cuối sc

 Nếu số i nào thỏa điều kiện i = (sd + sc)2 thì in số i vào file kết quả (có 3 số là

2025, 3025 và 9801

Trang 8

Hướng giải quyết:

- Vì đề thi không nói nhập số phần tử n từ đâu nên chúng ta có thể nhập từ bàn phím

- Tạo n số ngẫu nhiên từ 0 đến 9 và ghi vào file RANDOM.INP

- Sắp thứ tự mảng A tăng dần

Trang 9

- Đếm số phần tử = 0, số phần tử = 1,số phần tử = 2, …, số phần tử = 9:

 Dùng vòng For i:=0 to 9

 Biến đếm lấy giá trị 0

 Dùng vòng For j:=1 to n, nếu số i cần đếm = phần tử a[j] thì tăng biến đếm

 In kết quả ra file RANDOM.OUP

If a[i]>a[j] then Begin

t:=a[i]; a[i]:=a[j]; a[j]:=t;

End;

Assign(Output, 'RANDOM.OUP');

ReWrite(Output);

// In mảng dãy số ngẫu nhiên ra file

For i:=1 to n do Write(a[i], ' '); WriteLn;

// Đếm số lần xuất hiện của các số từ 0 đến 9 và in ra file

For i:=0 to 9 do Begin

Trang 10

Hướng giải quyết:

- Xét số lớn là a trong hai số (nếu a < b thì hoán đổi giá trị của a và b), ghi các ước số của

số này vào mảng Uoc_a

- Xét số nhỏ hơn là b, nếu các ước số của a cũng là các ước số của b thì hai số là nguyên

tố tương đương; ngược lại thì không là số nguyên tố tương đương

Lập trình như sau:

Var

Uoc_a: Array [1 1000000] of LongInt;

SPT_a, t, a, b, Luu_a, i, Dem, SNTi: LongInt;

For i:=2 to Trunc(SQRT(k)) do

If k mod i=0 then Exit(False);

Exit(True);

End;

{ -} Function SNT(k: LongInt): LongInt;

Trang 11

End;

Exit(i);

End;

{ -} Begin

If a=b then Begin Write(1); Close(Output); Exit; End;

If a<b then Begin t:=a; a:=b; b:=t; End;

For i:=1 to SPT_a do

If b mod Uoc_a[i]<>0 then Begin NTTD:=False; Break; End;

If NTTD then Write(1) else Write(0);

Close(Output);

End

(Xem tiếp bài 4 ở trang kế)

Trang 12

Hướng giải quyết:

- Dùng hàm Pos(Chuổi con, Chuổi) để tìm vị trí của khóa k1 trong mật mã Nếu tìm được thì tăng biến đếm 1 (Dem_1) và thay thế các ký tự này bằng ký tự -

- Nếu Dem_1>1 và Dem_2>1

 Nếu Dem_1=Dem_2 thì xuất k1+k2, ngược lại nếu k1>k2 thì xuất k1, còn không thì xuất k2

 Ngược lại thì xuất „NULL‟

Trang 13

If (Dem_1>1) and (Dem_2>1) then

If Dem_1=Dem_2 then Write(k1+k2)

Trang 14

Đề thi Tin học trẻ tỉnh Ninh Bình năm 2019

Khối Trung học Cơ sở Thời gian làm bài: 120 phút

Hướng giải quyết:

- Tìm ước chung lớn nhất (UCLN) của 2 số a và b:

 Nếu a=b thì UCLN=a hay b

Nếu a>b thì a:=a mod b, ngược lại b:=b mod a Thực hiện cho đến khi nào a mod b=0 hay b mod a=0 thì xuất ra số nhỏ trong 2 số

- TD: Tìm UCLN của 91 và 287

 Do 91 < 287 nên chúng ta tiếp tục tìm UCLN của 91 và 287 mod 91 (=14),

nghĩa là tìm UCLN của 91 và 14

Trang 15

 Do 91 > 14 nên chúng ta tiếp tục tìm UCLN của 91 mod 14 (=7) và 14, nghĩa là tìm UCLN của 7 và 14

 Do 14 mod 7=0 nên chúng ta xuất ra số nhỏ là 7

- Tìm UCLN của 3 số a, b, c:

 Đặt biến UC là UCLN của a và b

 Tìm UCLN của UC và biến c

Begin

While (a mod b<>0) and (b mod a<>0) do Begin

If a>b then a:=a mod b;

If (a mod b=0) or (b mod a=0) then Break;

If b>a then b:=b mod a;

End;

If a=b then Exit(a);

If a>b then Exit(b) else Exit(a);

End;

{====================================================================} Begin

Trang 16

Hướng giải quyết:

- Nếu chúng ta có 4 số a1, a2, a3, a4:

 Lấy a1 so sánh với a2, a3, a4

 Lấy a2 so sánh với a3, a4

 Lấy a3 so sánh với a4

Nghĩa là chúng ta dùng hai vòng lệnh For như sau:

For i:=1 to n-1 do (chạy tới n-1 mới có số phía sau)

For j:=i+1 to n do … (i=1 thì j chạy từ 2 đến số cuối thứ 4 là các số phía sau, i=2 thì j chạy từ 3 đến số cuối thứ 4, …)

- Hai vòng For này chạy lần thứ 1 để đếm số cặp bằng nhau

- Chạy lần 2 hai vòng For này để xuất ra các cặp số bằng nhau

Trang 17

If a[i]=a[j] then Begin

WriteLn('a',i,' = a',j,' = ',a[i]);

Trang 18

Hướng giải quyết:

- Khi gặp input là chuổi, nên đọc nguyên chuổi vào rồi tách ra từng từ dựa theo khoảng trắng ' ' giữa hai từ

- Đánh dấu các từ chỉ chứa số như '108', '71', … bằng mảng boolean La_So (là số)

- Chỉ sắp thứ tự các từ i là số như trên (La_So[i] = True)

 Đối từ thứ i là '108' sang dạng số So_i = 108

 Đối từ thứ j là '71' sang dạng số So_j = 71

 So sánh So_i và So_j để sắp xếp tăng dần

Trang 19

Ch:=Ch+' '; // Nếu không thêm ' ' vào cuối chuổi, từ cuối sẽ bị mất

For i:=1 to Length(Ch) do

If Ch[i]=' ' then Begin // Khi duyệt hết một từ, tăng số từ, gán vào

Inc(So_Tu); // mảng a, xóa từ để tạo từ mới

For i:=1 to n do Begin

Val(a[i], So, Loi);

If Loi=0 then La_So[i]:=True;

End;

// Sắp thứ tự tăng dần

For i:=1 to n-1 do

For j:=i+1 to n do

If La_So[i] and La_So[j] then Begin // Chỉ sắp xếp các từ là số

Val(a[i], So_i, Loi); // Đổi thành số để so sánh, vì trong so

Val(a[j], So_j, Loi); // sánh chuổi, ‘108’ < ‘71’ do ‘1’ < ‘7’

If So_i>So_j then Begin

Tu:=a[i]; a[i]:=a[j]; a[j]:=Tu;

Trang 20

Đề thi Tin học trẻ tỉnh Lâm Đồng năm 2019

Khối Trung học Cơ sở Thời gian làm bài: 150 phút

Hướng giải quyết:

Thay vì dùng 2 vòng For p:=1 to A và For q:=1 to B để tìm hai số p, q thỏa điều kiện

p+q=A và p*q=B thì chúng ta chỉ cần dùng một vòng For p:=1 to A-1 với q=A-p (chạy đến A-1 vì q>=1 và p+q=A)

Trang 21

Hướng giải quyết:

- Dùng vòng For i:=1 to n để nối các chữ số của số i vào chuổi Ch Nếu n=11 thì

Ch=‟1234567891011‟

- Do n <501 nên dùng {$H+} để mở rộng độ dài của chuổi mới chứa đủ các chữ số trong trường hợp n có giá trị lớn

- Muốn cắt bỏ k=10 số của chuổi số Ch=‟1234567891011‟ thì dùng nguyên tắc sau:

 Đi từ đầu đến ký tự kế cuối của chuổi ‟1 2 34567891011‟

 Bắt đầu là số 1, nếu phía sau số 1 có số lớn hơn (số 2) thì xóa số 1 và tăng biến đếm (Dem=1) => „2 3 456789101 1‟

 Tiếp tục là số 2, nếu phía sau số 2 có số lớn hơn (số 3) thì xóa số 2 và tăng biến đếm (Dem=2) => „3456789101 1‟

 Nếu biến Dem=k thì ngưng

 Khi chạy xong vòng For chuổi Ch=‟9111‟, nếu biến Dem (=9) vẫn còn < k (10)

Trang 22

Lập trình như sau:

{$H+} // Sử dụng để có Ch chuổi dài hơn do số n < 501

Var

n, i, j, K, Dem, L: Integer; Ch, Ch_i: String;

Co_Lon_Hon: Boolean; // True nếu sau số hiện tại có số lớn hơn nó

// Xóa k số để thu được số lớn nhất

L:=Length(Ch); Dem:=0; i:=1;

While (i < L-1) and (Dem<k) do Begin

Co_Lon_Hon:=False;

For j:=i+1 to L do

If Ch[i]<Ch[j] then Begin Co_Lon_Hon:=True; Break; End;

If Co_Lon_Hon then Begin

Delete(Ch, i, 1); Dec(L); Inc(Dem); Dec(i);

End;

Inc(i);

End;

If Dem < K then Ch:=Copy(Ch,1,L-(K-Dem)); // Nếu xóa chưa đủ k thì

// xóa thêm các số cuối

Trang 23

Hướng giải quyết:

- Dùng thuật toán Vết dầu loang (Loang) để đếm số cây liền nhau trên cùng hàng hay

cùng cột của mỗi phần tử a[i,j]

i, j-1 i, j i, j+1

Trang 24

Var Dem_Doc, Dem_Ngang, Luu_d, Luu_c: Integer; // Đếm dọc, ngang, lưu dòng

Dem_Doc:=1; Luu_d:=d; // Lưu lại giá trị dòng hiện thời là d

While (d>1) and (a[d-1,c]=a[Luu_d,c]) do Begin Inc(Dem_Doc); Dec(d); End; d:=Luu_d;

While (d<m) and (a[d+1,c]=a[Luu_d,c]) do Begin Inc(Dem_Doc); Inc(d); End; d:=Luu_d;

Dem_Ngang:=1; Luu_c:=c; // Lưu lại giá trị cột hiện thời là c

While (c>1) and (a[d,c-1]=a[d,Luu_c]) do Begin Inc(Dem_Ngang); Dec(c); End; c:=Luu_c;

While (c<n) and (a[d,c+1]=a[d,Luu_c]) do Begin Inc(Dem_Ngang); Inc(c); End;

If Dem_Doc>=Dem_Ngang then Exit(Dem_Doc)

else Exit(Dem_Ngang);

End;

{===========================================================================} Begin

Trang 25

Đề thi Tin học trẻ huyện Vũ Quang năm 2019

Khối Trung học Cơ sở Thời gian làm bài: 150 phút

Hướng giải quyết:

Trang 26

- Tuy nhiên cách này sẽ chạy chậm khi n là số lớn (=109)

Lập trình theo cách thứ nhất như sau:

Trang 27

Hướng giải quyết thứ hai:

- Cách thứ hai là thống kê số chữ số, lập công thức rồi tính số chữ số của số n

 Từ 0 9 có 10 chữ số

 Từ 10 99 có (99-10+1=90) số, mỗi số có 2 chữ số => có 90x2=180 chữ số Vậy từ 0 99 có 10+180=190 chữ số

Trang 28

i:=1; LT10:=10; // Tìm đoạn xem n nằm trong đoạn nào 0 9, 0.99,

While n>LT10-1 do Begin LT10:=LT10*10; Inc(i); End;

Trang 29

Hướng giải quyết:

- So sánh:

 a[1] với a[2], a[3], … cho đến a[n]

 a[2] với a[3], a[4], … cho đến a[n]

 a[i] với a[i+1], a[i+2], … cho đến a[n]

 a[n-1] với a[n]

- Dùng 2 vòng For:

 Biến Boolean DonNhat=True (Đơn nhất)

 For i:=1 to n-1

For j:=i+1 to n

Nếu a[i]=a[j] thì DonNhat=False và thoát vòng For

 Nếu DonNhat thì xuất số 1, ngược lại xuất số 0

Trang 30

Đề thi Tin học trẻ tỉnh Gia Lai năm 2019

Khối Trung học Cơ sở Thời gian làm bài: 150 phút

Hướng giải quyết:

- Có thể nhập số n từ bàn phím vì đề thi không nói đến file Input và Output

- Thay vì nhập biến n là số, có thể nhập biến n là chuổi (string) để dễ xử lý hơn và nhập

WriteLn('Ban hay nhap so n');

ReadLn(n); // Đọc số n theo dạng chuổi (String) để dễ xử lý

For i:=Length(n) downto 1 do

Write(n[i]);

End

Trang 31

Hướng giải quyết:

- Nhập chuổi Ch=‟12/15‟

- Dùng hàm Pos để tìm vị trí vt của „/‟ (vt=3)

- Tử số là chuổi con từ vị trí đến vt-1 (1 đến 2)

- Mẫu số là chuổi con từ vị trí đến vt+1 đến cuối (4 đến 5)

- Đổi tử số và mẫu số sang dạng số bằng hàm Val(chuỗi, số, lỗi)

- Tìm ước số chung lớn nhất (UC) của tử số và mẫu số (=3) (bạn hãy tham khảo trang 14

và 15)

- Chia tử số và mẫu số cho UC

- Xuất kết quả (tử số, „/‟, mẫu số)

Begin

While (a mod b<>0) and (b mod a<>0) do Begin

If a>b then a:=a mod b;

If (a mod b=0) or (b mod a=0) then Break;

If b>a then b:=b mod a;

End;

If a=b then Exit(a);

If a>b then Exit(b) else Exit(a);

End;

{====================================================================} Begin

WriteLn('Ban hay nhap phan so');

Trang 32

MS:=MS div UC;

WriteLn(TS, '/', MS);

End

Hướng giải quyết:

- Xuất phát với các biến i=1; độ dài L của chuổi (1234…) là 1 và tổng (Tong)=1

- Cho i tăng (-> 2, 3, 4…), biến i thành chuổi Dùng hàm Val để đổi từng chữ số của i thành số và cộng vào biến tổng, tăng giá trị của L lên 1

- Khi nào L=n là số chữ số cần tính tổng thì ngưng

For j:=1 to Length(Ch) do Begin

Val(Ch[j], So, Loi);

Trang 33

Hướng giải quyết:

- Dùng 2 vòng For i chạy từ 1 đến m-1 và For j chạy từ 1 đến n-1 để duyệt từng phần tử a[i,j] của ma trận m x n

i+1, j i+1, j+1 m-1, n-1

Trang 34

- Với mỗi phần tử a[i,j], hình vuông đồng nhất bậc 2 gồm các ô a[i,j], a[i+1,j], a[i, j+1] và a[i+1, j+1]

- Nếu 4 ô này bằng nhau thì tăng giá trị phần tử đếm (Dem[a[i,j]]) TD: a[i,j]=1 thì tăng giá trị Dem[1]

- Cuối cùng tìm giá trị lớn nhất Max của mảng Dem

Ngày đăng: 21/06/2020, 11:33

TỪ KHÓA LIÊN QUAN

TRÍCH ĐOẠN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w