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 1,2,3 Anh

Page 1

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ THCS

vectorstock.com/24597468

Ths Nguyễn Thanh Tú eBook Collection

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 1,2,3 (Nguyễn Anh Việt) WORD VERSION | 2022 EDITION ORDER NOW / CHUYỂN GIAO QUA EMAIL TAILIEUCHUANTHAMKHAO@GMAIL.COM

Tài liệu chuẩn tham khảo Phát triển kênh bởi Ths Nguyễn Thanh Tú Đơn vị tài trợ / phát hành / chia sẻ học thuật : Nguyen Thanh Tu Group Hỗ trợ trực tuyến Fb www.facebook.com/DayKemQuyNhon Mobi/Zalo 0905779594


QU Y

NH

ƠN

OF

Thời gian làm bài: 120 phút.

Hướng giải quyết:

M

DẠ

Y

-

Với n=7 có 3 lần so sánh: Số thứ 1 (3) và thứ 7 (3) Số thứ 2 (6) và thứ 6 (6) Số thứ 3 (1) và thứ 5 (1) Với n=8 có các số của dãy số là 3 6 1 2 2 1 6 3 có 4 lần so sánh: Số thứ 1 (3) và thứ 8 (3) Số thứ 2 (6) và thứ 7 (6) Số thứ 3 (1) và thứ 6 (1) Số thứ 4 (1) và thứ 5 (2)

-

Số lần so sánh sẽ là n div 2

L

Khối Trung học Cơ sở

FI CI A

Đề thi Tin học trẻ Thành phố Hà Nội năm 2016


số thứ 1 so sánh với số thứ 7 số thứ 2 so sánh với số thứ 6 số thứ 3 so sánh với số thứ 5

L

Với n=7,

FI CI A

-

Vậy số thứ i sẽ so sánh với số thứ n+1-i -

Trong quá trình so sánh chỉ cần số thứ i khác với số thứ n+1-i thì dãy đã cho là không đối xứng nên cần thông báo kết quả và kết thúc, không cần so sánh thêm nữa.

đứng trước là chú thích, không cần viết vào chương trình)

OF

Chương trình viết trên Free Pascal như sau: (các dòng có màu xanh có //

QU Y

NH

ƠN

Var a: Array [1..100] of Integer; // De thi khong cho biet moi so cua day so nam // trong khoang nao n, i: Integer; Begin Assign(Input,'DaySo.Inp'); Reset(Input); ReadLn(n); For i:=1 to n do Read(a[i]); Close(Input);

DẠ

Y

M

Assign(Output,'DaySo.Out'); ReWrite(Output); For i:=1 to n do If a[i]<>a[n+1-i] then Begin Write(0); Close(Output); Exit; End; // Neu day so khong doi xung thi da ghi ket qua va // thoat chuong trinh. Write(1); Close(Output); End.


L FI CI A OF ƠN

Hướng giải quyết:

Tìm vị trí của số 1 (3), dò từ 1 đến 2 đếm các số lớn hơn 1 có 5, 9 => 2 Tìm vị trí của số 2 (5), dò từ 1 đến 4 đếm các số lớn hơn 2 có 5, 9, 8 => 3 Tìm vị trí của số 3 (9), dò từ 1 đến 8 đếm các số lớn hơn 3 có 5, 9, 8, 6, 4, 7 => 6 Tìm vị trí số thứ i (vt), dò từ 1 đến vt-1 đếm các số lớn hơn i

NH

-

QU Y

Chương trình viết như sau: (các dòng có màu xanh có // đứng trước là chú thích, không cần viết vào chương trình)

Y

M

Var n, i, j, vt, Dem: Integer; A, NT: Array [1..20] of Integer; // De thi khong cho biet gioi han cua n va cac so cua day // so Begin Write('Ban hay nhap so n '); ReadLn(n); WriteLn('Ban hay nhap ', n, ' so cua hoan vi '); For i:=1 to n do Read(A[i]);

DẠ

For i:=1 to n do Begin Dem:=0; // Tim vi tri vt cua i For vt:=1 to n do If i=A[vt] then Break;


L

// Dem

FI CI A

For j:=1 to vt-1 do If A[j]>i then Inc(Dem); NT[i]:=Dem; End;

M

QU Y

NH

ƠN

OF

WriteLn('Nghich the cua hoan vi:'); For i:=1 to n do Write(NT[i], ' '); End.

-

Tạo chuổi A bằng các ghép các số từ 1 đến n. Do chuổi chỉ có 256 ký tự nên cần khai báo {$H+} để chuổi chứa được nhiều chữ số hơn (n<=100) Chữ số thứ k chính là A[k]

DẠ

Y

-

Hướng giải quyết:


L

Chương trình viết như sau:

DẠ

Y

M

QU Y

OF

NH

Assign(Output, 'So.Out'); ReWrite(Output); WriteLn(A); WriteLn(A[k]); Close(output); End.

ƠN

A:=''; For i:=1 to n do Begin Str(i, Ch); A:=A+Ch; End;

FI CI A

{$H+} Var n, k, i: Integer; A, Ch: String; Begin Assign(Input, 'So.Inp'); Reset(Input); Read(n, k); Close(Input);


L

Đề thi Tin học trẻ huyện Hoa Lư năm 2018

QU Y

NH

ƠN

OF

Thời gian làm bài: 120 phút.

FI CI A

Khối Trung học Cơ sở

Hướng giải quyết:

DẠ

Y

M

 Sắp thứ tự dãy số: Với n<=10 000 có thể dùng cách sắp xếp thông thường: TD: Sắp thứ tự tăng dần dãy số 8 9 7: - So sánh số thứ 1 với số thứ 2 và 3, nếu lớn hơn thì đổi chỗ - 8 9 => giữ, 8 > 7 | 8 9 7 => 7 9 8 - So sánh số thứ 2 với số thứ 3, nếu lớn hơn thì đổi chỗ - 9 > 8 | 7 9 8 => 7 8 9  Sau khi sắp xếp dãy số tăng dần, TD: 3 7 9 22 36 56. Muốn chen số 15 vào dãy số: - Dò từ đầu dãy số, đến số nào lớn hơn số 15 thì ngưng => vị trí 4 - Chen số 71 lớn hơn số cuối cùng là 56 thì vị trí là n+1 => vị tri 7


OF

Begin Assign(Input,'XepCay.Inp'); Reset(Input); ReadLn(n); For i:=1 to n do Read(A[i]); ReadLn(k);

FI CI A

Const MaxN=10000; Var n, k, i, j, vt: Integer; A: Array [1..MaxN] of LongInt; t: LongInt;

L

Chương trình viết như sau:

NH

ƠN

// Sap thu tu day so 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; End;

QU Y

// Tim vi tri de chen so k vt:=1; While (k>A[vt]) and (vt<n) do Inc(vt); If vt=n then Inc(vt);

DẠ

Y

M

// Xuat ket qua Assign(Output, 'DaySo.Out'); ReWrite(Output); For i:=1 to n do Write(A[i], ' '); WriteLn; Write(vt); Close(Output); End.


L FI CI A OF ƠN NH

Hướng giải quyết:

 Tính độ dài đoạn thẳng AB theo công thức

Yb

B

AB = SQRT((SQR(Xb-Xa)+SQR(Yb-Ya)))

QU Y

 Tính diện tích tam giác theo công thức Heron: DT = SQRT(p.(p-a).(p-b).(p-c)) trong đó p là nửa chu vi của tam giác có 3 cạnh a, b, c

Ya A Xa

M

 Nếu điểm M nằm trong tam giác ABC thì diện tích tam giác (DT) DT MAB + DT MBC+ DT MAC = DT ABC

A

DẠ

Y

M B

C

Xb


FI CI A

L

 Tuy nhiên khi so sánh 2 số dạng số thực real cần làm một Function so sánh 2 số, nếu chênh lệch giữa 2 số < 0.0001 thì hai số là bằng nhau

Chương trình viết như sau: Var Xa,Ya,Xb,Yb,Xc,Yc,Xm,Ym: LongInt; DTabc, DT3tg: Real; Ch: String;

M

QU Y

NH

ƠN

OF

{-----------------------------------------------------} Function SoSanh(X,Y: Real): Boolean; Begin If abs(X-Y)<0.0001 then Exit(True) else Exit(False); End; {-----------------------------------------------------} Function DoDai(Xa,Ya,Xb,Yb: Integer): Real; Begin Exit(SQRT(SQR(Xb-Xa)+SQR(Yb-Ya))); End; {-----------------------------------------------------} Function DienTich(Xa,Ya,Xb,Yb,Xc,Yc: Integer): Real; Var a,b,c,p: Real; Begin a:=DoDai(Xb,Yb,Xc,Yc); b:=DoDai(Xa,Ya,Xc,Yc); c:=DoDai(Xa,Ya,Xb,Yb); p:=(a+b+c)/2; Exit(SQRT(p*(p-a)*(p-b)*(p-c))); End; {=====================================================} Begin Assign(Input,'TamGiac.Inp'); Reset(Input); Read(Xa, Ya, Xb, Yb, Xc, Yc, Xm, Ym); Close(Input); DTabc:=DienTich(Xa,Ya,Xb,Yb,Xc,Yc); DT3tg:=DienTich(Xm,Ym,Xa,Ya,Xb,Yb) +DienTich(Xm,Ym,Xb,Yb,Xc,Yc) +DienTich(Xm,Ym,Xc,Yc,Xa,Ya); // Bo so khoang trang dung truoc Str(DTabc:10:2,Ch); While (Ch[1]=' ') and (Length(Ch)>1) do Delete(Ch,1,1);

DẠ

Y

Assign(Output,'TamGiac.Out'); ReWrite(Output); WriteLn(Ch); If SoSanh(DTabc,DT3tg) then Write('Trong') else Write('Ngoai'); Close(Output); End.


L FI CI A OF

Hướng giải quyết:

QU Y

NH

ƠN

 Làm Function xét xem một số k có phải là số nguyên tố hay không: - Nếu k<2 => k không phải là số nguyên tố, thoát Function - Thử lấy số dư k chia các giá trị từ 2 đến căn bậc 2 của số k, td: k=17 thì thử các giá trị từ 2 đến 4, nếu chia hết (số dư = 0) => k không phải là số nguyên tố, thoát Function - Đến đây thì k là số nguyên tố.  Tìm số nguyên tố ghép thứ k: - Xuất phát từ 2 số nguyên tố đầu tiên là 2 và 3, i=4, số nguyên tố ghép là 23, biến đếm=1 - (*) Tăng i đến khi nào là số nguyên tố thì ngưng (i=5), NT1=i=5, tăng i lên 1 (i=6) Tăng i đến khi nào là số nguyên tố thì ngưng (i=7), NT1=i=7, tăng i lên 1 (i=8) - Ghép NT1 và NT2 (57) không là số nguyên tố ghép - Nếu là số nguyên tố ghép (31 và 37 thành 3137) => tăng biến đếm (=2) - Lặp lại bước (*) đến khi biến đếm=k thì ngưng

M

Chương trình viết như sau:

DẠ

Y

Var i, k: QWord; Loi: Integer; Ghep, Dem, LT10, NT1, NT2: QWord; Ch1, Ch2: String; {-----------------------------------------------------} Function NT(k: QWord): Boolean; Var i: LongInt; Begin If k<2 then Exit(False); For i:=2 to Trunc(SQRT(k)) do


NH

ƠN

OF

FI CI A

L

If k mod i=0 then Exit(False); Exit(True); End; {=====================================================} Begin Assign(Input, 'NTGhep.Inp'); Reset(Input); Read(k); Close(Input); NT1:=2; NT2:=3; Dem:=1; i:=4; While Dem<k do Begin While Not NT(i) do Inc(i); NT1:=i; Inc(i); While Not NT(i) do Inc(i); NT2:=i; Inc(i); Str(NT1,Ch1); Str(NT2,Ch2); Val(Ch1+Ch2,Ghep,Loi); If NT(Ghep) then Inc(Dem); End; Assign(Output, 'NTGhep.Out'); ReWrite(Output); Write(Ghep); Close(Output); End.

Chú ý:

Với k khá lớn (500) thì chương trình chạy vẫn được nhưng chậm Có thể dùng sàng nguyên tố Erastothenes giải quyết để chương trình đáp ứng được thời gian (sẽ đề cập sau này trong các bài toán về số nguyên tố nâng cao trong các tập tiếp theo ).

DẠ

Y

M

QU Y

-


L

Đề thi Tin học trẻ TP. Qui Nhơn năm 2018

OF

Thời gian làm bài: 150 phút.

FI CI A

Khối Trung học Cơ sở

Hướng giải quyết:

QU Y

NH

ƠN

 Làm Function xét xem một số k có phải là số nguyên tố hay không (tham khảo câu 3 – Đề thi huyện Hoa Lư năm 2018)  Phân tích số 120 thành thừa số nguyên tố: - Đặt biến NT=2 - (*) Trong khi n=120 chia hết cho 2 thì ghi kết quả và chia 120 cho 2: 120 -> 60 -> 30 ->15 => 2*2*2 - Tăng NT lên 1 (3), trong khi NT không phải là số nguyên tố thì tăng giá trị của NT - Thực hiện lại bước (*) trong khi n>1: NT=3: 15 -> 5 => 2*2*2*3 NT=5: 5 -> 1 => 2*2*2*3*5

Chương trình viết như sau:

DẠ

Y

M

Var n, NT: LongInt; {---------------------------------------------------------} Function SNT(k: LongInt): Boolean; Var i: Integer; 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; {=========================================================} Begin WriteLn('Hay nhap so can phan tich thanh thua so NT'); ReadLn(n);


L

ƠN

OF

FI CI A

NT:=2; Write(n,'='); While n>1 do Begin While n mod NT=0 do Begin // So cuoi khong ghi dau * If n<>NT then Write(NT,'*') else Write(NT); n:=n div NT; End; Inc(NT); While not SNT(NT) do Inc(NT); End; End.

NH

Hướng giải quyết:

''

'10'

QU Y

 Tách chuổi thi10tin21hoc9tre5nam2018 thành: - Chuổi từ: 'thi' '' 'tin' '' 'hoc' '' 'tre' '' 'nam' '' - Chuổi số: '' '10' '' '21' '' '9' '' '5' '' '2018'  Sắp thứ tự chuổi số: ''

'21'

 '' '5' '' '9'  Nối lại thành chuổi: 'thi' ''

'' 'tin' '5' ''

''

''

'9'

''

'5'

''

'2018'

'10'

''

'21'

''

'2018'

'' 'hoc' '' 'tre' '' 'nam' '' '9' '' '10' '' '21' '' '2018'

M

 thi5tin9hoc10tre21nam2018  Chú ý: Khi sắp thứ tự cần đổi chuổi thành số bằng hàm Val, nếu không sẽ bị sai kết quả do khi so sánh chuổi ta lại có '21' > '2018'.

Chương trình viết như sau:

DẠ

Y

Var Ch: String; i, j, Dem, SoI, SoJ, Loi: Integer; So, Tu: Array [1..100] of String; Tam: String; Begin Write('Ban hay nhap chuoi can sap thu tu '); ReadLn(Ch); i:=1; Dem:=0; // Tach tu va so


DẠ

Y

M

QU Y

NH

ƠN

OF

FI CI A

L

While i<length(Ch) do Begin If Pos(Ch[i],'0123456789')>0 then Begin // Ch[i] la so Inc(Dem); While Pos(Ch[i],'0123456789')>0 do Begin So[Dem]:=So[Dem]+Ch[i]; Inc(i); End; End else Begin // Ch[i] la chu Inc(Dem); While Pos(Ch[i],'0123456789')=0 do Begin Tu[Dem]:=Tu[Dem]+Ch[i]; Inc(i); End; End; End; // Sap thu tu day so For i:=1 to Dem-1 do For j:=i+1 to Dem do Begin Val(So[i], SoI, Loi); Val(So[j], SoJ, Loi); If (So[i]<>'') and (So[j]<>'') and (SoI>SoJ) then Begin Tam:=So[i]; So[i]:=So[j]; So[j]:=Tam; End; End; // Noi tu va so Ch:=''; For i:=1 to Dem do Begin If So[i]<>'' then Ch:=Ch+So[i]; If Tu[i]<>'' then Ch:=Ch+Tu[i]; End; Write('Chuoi da sap thu tu la: ', Ch); End.


L FI CI A OF

Hướng giải quyết:

ƠN

 Dùng hàm EOF() để đọc file Input khi không cho biết số dòng.  Dùng hàm Trim để cắt bỏ các khoảng trắng khi dịnh dạng số thực Real

Chương trình viết như sau:

NH

Uses SysUtils; // Dung ham trim Var Ch, ChTB: String; Min, Max, Tong, n: LongInt;

QU Y

Begin Assign(Input, 'DuLieu.Inp'); Reset(Input);

M

Min:=MaxLongInt; Max:=-MaxLongInt; While not EOF() do Begin ReadLn(Ch); Inc(n); Tong:=Tong+Length(Ch); If Min>Length(Ch) then Min:=Length(Ch); If Max<Length(Ch) then Max:=Length(Ch); End; Close(Input);

DẠ

Y

WriteLn('So ky tu dong ngan nhat: ', Min); WriteLn('So ky tu dong dai nhat: ', Max); Str(Tong/n:20:1, ChTB); WriteLn('So ky tu trung binh cac dong: ', Trim(ChTB)); End.


L FI CI A OF

Hướng giải quyết:   -

QU Y

NH

ƠN

Tìm ước chung lớn nhất (UCLN) của 2 số bằng cách: (*) Nếu a>b => a:=a-b, ngược lại b:=b-a Lặp lại bước (*) cho đến khi a=b thì UCLN là a hay b Tìm ước chung lớn nhất (UCLN) của nhiều số a1, a2, a3…, an bằng cách: Đặt biến UC=UCLN(a1,a2) Tìm UC:=UCLN(UC,ai) với i chạy từ 3 đến n UC chính là UCLN của dãy số  Tìm bội chung nhỏ nhất (BCNN) của 2 số bằng cách: BCNN(a,b)=a*b div UCLN(a,b)  Tìm bội chung nhỏ nhất của nhiều số a1, a2, a3…, an bằng cách: - Đặt biến BC=BCNN(a1,a2); - Tìm BC:=BCNN(BC,ai) với i chạy từ 3 đến n BC chính là BCNN của dãy số

Chương trình viết như sau:

DẠ

Y

M

Var n, i: Integer; A: Array [1..1000] of LongInt; BC: LongInt; {---------------------------------------------------------} Function UCLN(a,b: LongInt): LongInt; Begin While a<>b do If a>b then a:=a-b else b:=b-a; Exit(a); End; {---------------------------------------------------------} Function BCNN(a,b: LongInt): LongInt; Begin


BC:=BCNN(A[1],A[2]); For i:=3 to n do BC:=BCNN(BC,A[i]);

OF

FI CI A

L

Exit(a*b div UCLN(a,b)); End; {=========================================================} Begin Assign(Input,'DaySo.Inp'); Reset(Input); While not EOF() do Begin Inc(n); Read(A[n]); End; Close(Input);

DẠ

Y

M

QU Y

NH

ƠN

Assign(Output,'DaySo.Out'); ReWrite(Output); WriteLn(BC); Close(Output); End.


L

Đề thi Tin học trẻ TP. Ninh Bình năm 2018

ƠN

OF

Thời gian làm bài: 120 phút.

FI CI A

Khối Trung học Cơ sở

NH

Hướng giải quyết:

QU Y

 Đối với các đề bài có liên quan đến số nguyên tố, đầu tiên nên viết một Function NT để xét một số có phải là số nguyên tố hay không  Vòng lặp While true do …. Sẽ chạy vô điều kiện và chạy hoài đến khi nào chúng ta tìm được kết quả và Break nó - Đặt biến NT1 là số nguyên tố đầu tiên (là 2) - (*) Đặt biến NT2 là NT1+1 (là 3), nếu chưa phải là số nguyên tố thì tăng NT2 đến khi nào là số nguyên tố thì ngưng. Do 3 là số nguyên tố nên NT2=3 không tăng - Nếu NT2-NT1>=k thì Break - Gán NT1:=NT2 (là 3) và quay trở lại bước (*)

M

Chương trình viết như sau:

DẠ

Y

Var k: Integer; NT1, NT2: 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);


FI CI A

L

End; {=====================================================} Begin Assign(Input,'NgTo.Inp'); Reset(Input); Read(k); Close(Input);

M

QU Y

NH

ƠN

OF

NT1:=2; While true do Begin NT2:=NT1+1; While not NT(NT2) do Inc(NT2); If NT2-NT1>=k then Break; NT1:=NT2; End; Assign(Output, 'NgTo.Out'); ReWrite(Output); Write(NT1, ' ', NT2); Close(Output); End.

Hướng giải quyết:

DẠ

Y

 Tìm Min và Max của dãy số, TD: 9 7 14 10 11 thì Min=7 và Max=14  Viết Function tìm một số k có trong dãy số đã cho hay không  Dùng vòng For với biến i chạy từ Min (7) đến Max (14) quét trên dãy số, nếu giá trị i không có trong dãy số thì cộng dồn vào biến tổng.


L

 Chương trình viết như sau:

QU Y

NH

ƠN

OF

FI CI A

Var n, i: Integer; A: Array [1..10000] of LongInt; Min, Max: LongInt; Tong: QWord; {---------------------------------------------------------} Function TimSo(k: LongInt): Boolean; Var i: Integer; Begin For i:=1 to n do If k=A[i] then Exit(True); Exit(False); End; {=========================================================} Begin Assign(Input,'DaySo.Inp'); Reset(Input); ReadLn(n); For i:=1 to n do Read(A[i]); Close(Input); // Tim Min va Max Min:=A[1]; Max:=A[1]; For i:=2 to n do Begin If Min>A[i] then Min:=A[i]; If Max<A[i] then Max:=A[i]; End;

DẠ

Y

M

// Tong cac so khong co trong day so For i:=Min to Max do If not TimSo(i) then Tong:=Tong+i; Assign(Output,'DaySo.Out'); ReWrite(Output); WriteLn(Min, ' ', Max); Write(Tong); Close(Output); End.


L FI CI A OF ƠN NH QU Y

Hướng giải quyết:

DẠ

Y

M

 Thời điểm sớm nhất tất cả các bóng đèn sẽ sáng là bội số chung nhỏ nhất của dãy số chu kỳ. TD: - Đèn 1 có chu kỳ 4 sẽ sáng tại các thời điểm 4, 8, 12, 16… - Đèn 2 có chu kỳ 6 sẽ sáng tại các thời điểm 6, 12, 18… - Thời điểm sớm nhất 2 bóng đèn sẽ sáng là 12, chính là bội chung nhỏ nhất của 4 và 6.


L

Chương trình viết như sau:

QU Y

NH

ƠN

OF

FI CI A

Var n, i: Integer; A: Array [1..1000] of LongInt; BC: LongInt; {---------------------------------------------------------} Function UCLN(a,b: LongInt): LongInt; Begin While a<>b do If a>b then a:=a-b else b:=b-a; Exit(a); End; {---------------------------------------------------------} Function BCNN(a,b: LongInt): LongInt; Begin Exit(a*b div UCLN(a,b)); End; {=========================================================} Begin Assign(Input,'DenNhay.Inp'); Reset(Input); While not EOF() do Begin Inc(n); Read(A[n]); End; Close(Input); BC:=BCNN(A[1],A[2]); For i:=3 to n do BC:=BCNN(BC,A[i]);

DẠ

Y

M

Assign(Output,'DenNhay.Out'); ReWrite(Output); WriteLn(BC); Close(Output); End.


QU Y

NH

ƠN

OF

FI CI A

Đề 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.

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

M

Hướng giải quyết:

DẠ

Y

- 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:  234 mod 10 (phép chia lấy số dư, 234 / 10 =23 dư 4) = 4  234 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:  Nếu k < 2 => không là số nguyên tố  Nếu k >= 2 : Chia số k cho i với i lấy giá trị từ 2 đến căn của số k cắt bỏ số lẻ. TD: số 11 thì chia thử cho 2 đến 3 đều không chia hết => 11 là số nguyên tố Trang 1

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

L

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

FI CI A

Lập trình như sau:

QU Y

NH

ƠN

OF

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; Begin Tong_BP:=0; While k>0 do Begin Tong_BP:=Tong_BP+SQR(k mod 10); k:=k div 10; End; If NT(Tong_BP) then Exit(True) else Exit(False); End; {====================================================================} Begin Assign(Input, 'SODEP.INP'); Reset(Input); Assign(Output, 'SODEP.OUT'); ReWrite(Output);

DẠ

Y

M

While not EOF() do Begin ReadLn(n); Dem:=0; So:=10; While Dem<n do Begin If SoDep(So) then Inc(Dem); Inc(So); End; WriteLn(So-1); // Do lệnh Inc(So) nên So-1 mới là số đẹp End; Close(Input); Close(Output); End.

Trang 2

Biên soạn: Th.S Nguyễn Anh Việt


ƠN

OF

FI CI A

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

NH

Hướng giải quyết:

Lập trình như sau:

QU Y

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

DẠ

Y

M

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 n, i, j, t: Integer; Tong_TL: Integer; Begin Assign(Input, 'THANGMAY.INP'); Reset(Input); i:=1; 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; Close(Input); n:=i-1; // Do lệnh Inc(i) nên số người là i-1

Trang 3

Biên soạn: Th.S Nguyễn Anh Việt


FI CI A

// 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 End;

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

OF

// Xếp vào thang máy sao cho <= 500 kg Tong_TL:=0; i:=1; While Tong_TL+a[i] <= 500 do Begin Tong_TL:=Tong_TL+a[i]; DD[TT[i]]:=True; // Đánh dấu những người được đi thang máy Inc(i); End;

DẠ

Y

M

QU Y

(Xem tiếp câu 3 ở trang kế)

NH

ƠN

Assign(Output, 'THANGMAY.OUT'); ReWrite(Output); For i:=1 to n do If DD[i] then Write(b[i],' '); // In theo thứ tự trong mảng b đã lưu WriteLn; Write(Tong_TL); Close(Output); End.

Trang 4

Biên soạn: Th.S Nguyễn Anh Việt


M

QU Y

NH

ƠN

OF

FI CI A

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

Hướng giải quyết:

DẠ

Y

- Đá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:  Xuất phát từ ô x1, y1  Đi qua ô nào thì đánh dấu ô đó là đã duyệt (DD[dòng, cột]:=1)  Nếu đi đến đích (ô hiện thời là x2, y2) thì ngưng (Exit) Trang 5

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

FI CI A

L

 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:

ReadLn(n, m); For i:=1 to n do For j:=1 to m do Read(a[i,j]);

QU Y

NH

ƠN

OF

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 Assign(Input, 'VUNG.INP'); Reset(Input);

DẠ

Y

M

Assign(Output, 'VUNG.OUT'); ReWrite(Output); 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 6

Biên soạn: Th.S Nguyễn Anh Việt


M

QU Y

NH

ƠN

OF

FI CI A

Đề 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.

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

Hướng giải quyết:

DẠ

Y

- Tách nhóm 2 số: ví dụ số 3025  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 7

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

L

Lập trình như sau:

FI CI A

Var i, sd, sc: Integer;

Y

M

QU Y

NH

ƠN

OF

Begin Assign(Output, 'sohoc.oup'); // Chú ý là .oup chứ không phải là .out ReWrite(Output); For i:=1000 to 9999 do Begin sc:=i mod 100; sd:=i div 100; If i = SQR(sd + sc) then WriteLn(i); End; Close(Output); End.

DẠ

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 8

Biên soạn: Th.S Nguyễn Anh Việt


FI CI A

- Đế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

Lập trình như sau: Var n, i, j, t, Dem: Integer; a: Array [1..105] of Integer;

ƠN

NH

Assign(Output, 'RANDOM.INP'); ReWrite(Output); For i:=1 to n do Write(a[i], ' '); Close(Output);

OF

Begin WriteLn('Ban hay nhap so phan tu n'); ReadLn(n); // Tạo n số ngẫu nhiên từ 0 đến 9 Randomize(); For i:=1 to n do Begin a[i]:=Random(10); End;

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

QU Y

// Sắp thứ tự mảng A tăng dần 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; End; Assign(Output, 'RANDOM.OUP'); ReWrite(Output);

M

// In mảng dãy số ngẫu nhiên ra file For i:=1 to n do Write(a[i], ' '); WriteLn;

DẠ

Y

// Đế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 Dem:=0; For j:=1 to n do If i=a[j] then Inc(Dem); WriteLn(Dem); End; Close(Output); End.

Trang 9

Biên soạn: Th.S Nguyễn Anh Việt


OF

FI CI A

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

ƠN

Hướng giải quyết:

Lập trình như sau:

QU Y

NH

- Số nguyên tố thứ 1.000.000 là 15.485.863 - Đề thi không cho biết giới hạn của hai số a, b cần xét có là số nguyên tố tương đương hay không nên có thể viết bài giải với giới hạn a, b <= 15.485.863 - Hai số bằng nhau chắc chắn là hai số nguyên tố tương đương vì có các ước số giống nhau - 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

DẠ

Y

M

Var Uoc_a: Array [1..1000000] of LongInt; SPT_a, t, a, b, Luu_a, i, Dem, SNTi: LongInt; NTTD: Boolean; 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 SNT(k: LongInt): LongInt; Var i: QWord; Begin i:=2; Dem:=1; While Dem<k do Begin Inc(i); If NT(i) then Inc(Dem);

Trang 10

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

FI CI A

L

End; Exit(i); End; {--------------------------------------------------------------------} Begin Assign(Input, 'TD.INP'); Reset(Input); ReadLn(a, b); Close(Input);

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

OF

Assign(Output, 'TD.UOP'); ReWrite(Output); If a=b then Begin Write(1); Close(Output); Exit; End;

NH

ƠN

i:=1; While Luu_a<>1 do Begin SNTi:=SNT(i); If Luu_a mod SNTi=0 then Begin Inc(SPT_a); Uoc_a[SPT_a]:=SNTi; End; While Luu_a mod SNTi=0 do Luu_a:=Luu_a div SNTi; Inc(i); End; NTTD:=True; For i:=1 to SPT_a do If b mod Uoc_a[i]<>0 then Begin NTTD:=False; Break; End;

QU Y

If NTTD then Write(1) else Write(0); Close(Output); End.

DẠ

Y

M

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

Trang 11

Biên soạn: Th.S Nguyễn Anh Việt


Hướng giải quyết:

QU Y

NH

ƠN

OF

FI CI A

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

- 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ự  Lần 1:  Lần 2:

M

Pos(‘12’ ,‘12bbb11122544466bbRb’)=1 | Dem_1=1 | => ‘--bbb11122544466bbRb’ Pos(‘12’ ,‘--bbb11122544466bbRb’)=8 | Dem_1=2 | => ‘--bbb11--2544466bbRb’

- Tương tự, tìm vị trí của khóa k2 trong mật mã  Lần 1: Pos(‘bb’,‘12bbb11122544466bbRb’)= 3 | Dem_2=1 | => ‘12--b11122544466bbRb’

 Lần 2:

Y

Pos(‘bb’,’12--b11122544466bbRb’)=16 | Dem_2=2 | => ‘12--b11122544466--Rb’

DẠ

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

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

L

Lập trình như sau:

FI CI A

Var P, Luu_P, k1, k2: String; i, Dem_1, Dem_2, VT: Integer;

OF

Begin Assign(Input, 'MAHOA.INP'); Reset(Input); ReadLn(P); ReadLn(k1); ReadLn(k2); Luu_P:=P; Close(Input);

NH

QU Y

P:=Luu_P; Dem_2:=0; While Pos(k2, P)>0 do Begin Inc(Dem_2); VT:=Pos(k2, P); Delete(P,VT,Length(k2)); For i:=1 to Length(k2) do Insert('-',P,VT); End;

ƠN

Dem_1:=0; While Pos(k1, P)>0 do Begin Inc(Dem_1); VT:=Pos(k1, P); Delete(P,VT,Length(k1)); For i:=1 to Length(k1) do Insert('-',P,VT); End;

DẠ

Y

M

Assign(Output, 'MAHOA.OUP'); Reset(Output); If (Dem_1>1) and (Dem_2>1) then If Dem_1=Dem_2 then Write(k1+k2) else If Dem_1>Dem_2 then Write(k1) else Write(k2) else Write('NULL'); Close(Output); End.

Trang 13

Biên soạn: Th.S Nguyễn Anh Việt


M

QU Y

NH

ƠN

OF

FI CI A

Đề 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.

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

Hướng giải quyết:

DẠ

Y

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

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

FI CI A

L

 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 - TD: Tìm UCLN của 6, 18 và 12:  UCLN của 6 và 18 là 6  UCLN của 6 và 12 là 6  Vậy UCLN của 3 số 6, 18 và 12 là 6

OF

Lập trình như sau:

QU Y

NH

ƠN

Var a, b, c, UC: LongInt; {--------------------------------------------------------------------} Function UCLN(a, b: LongInt): LongInt; 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 Assign(Input, 'UC.INP'); Reset(Input); ReadLn(a, b, c); UC:=UCLN(a, b); UC:=UCLN(UC, c);

DẠ

Y

M

Assign(Output, 'UC.OUT'); ReWrite(Output); WriteLn(UC); Close(Output); End.

Trang 15

Biên soạn: Th.S Nguyễn Anh Việt


NH

ƠN

OF

FI CI A

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

Hướng giải quyết:

M

QU Y

- 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

Lập trình như sau:

Y

Var n, i, j: LongInt; // Mảng có <=105 phần tử a: Array [1..100000] of LongInt; // Mỗi phần tử <=105 Dem: QWord;

DẠ

Begin Assign(Input, 'DC.INP'); Reset(Input); ReadLn(n); For i:= 1 to n do Read(a[i]);

Trang 16

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

// Đềm số cặp bằng nhau For i:=1 to n-1 do For j:=i+1 to n do If a[i]=a[j] then Inc(Dem);

ƠN

OF

// Xuất ra số cặp bằng nhau và các cặp số bằng nhau Assign(Output, 'DC.OUT'); ReWrite(Output); WriteLn('Co ', Dem, ' cap so bang nhau la:'); For i:=1 to n-1 do For j:=i+1 to n do If a[i]=a[j] then Begin WriteLn('a',i,' = a',j,' = ',a[i]); End; Close(Output); End.

FI CI A

L

Close(Input);

DẠ

Y

M

QU Y

NH

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

Trang 17

Biên soạn: Th.S Nguyễn Anh Việt


M

QU Y

NH

ƠN

OF

FI CI A

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

Hướng giải quyết:

DẠ

Y

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

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

Var Ch, Tu: String; n, i, j, So_Tu, So, So_i, So_j, Loi: Integer; a: Array [1..50] of String [25]; La_So: Array [1..50] of Boolean;

OF

Begin Assign(Input, 'XAU.INP'); Reset(Input); ReadLn(n); ReadLn(Ch); // Đọc vào nguyên chuổi chứa các từ Close(Input);

FI CI A

L

Lập trình như sau:

NH

ƠN

// Tách từng từ 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 a[So_Tu]:=Tu; Tu:=''; End else Tu:=Tu+Ch[i]; // Dồn các ký tự vào từ

QU Y

// Đánh dấu các từ chỉ chứa số For i:=1 to n do Begin Val(a[i], So, Loi); If Loi=0 then La_So[i]:=True; End;

M

// 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; End; End;

DẠ

Y

// Xuất kết quả Assign(Output, 'XAU.OUT'); ReWrite(Output); For i:=1 to n do Write(a[i], ' '); Close(Output); End.

Trang 19

Biên soạn: Th.S Nguyễn Anh Việt


Hướng giải quyết:

QU Y

NH

ƠN

OF

FI CI A

Đề 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.

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

M

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)

Lập trình như sau:

Y

Var A, B, p, q: Integer;

DẠ

Begin Assign(Input, 'TIMSO.INP'); Reset(Input); ReadLn(A); ReadLn(B); Close(Input);

Trang 20

Biên soạn: Th.S Nguyễn Anh Việt


Hướng giải quyết:

QU Y

NH

ƠN

OF

FI CI A

Assign(Output, 'TIMSO.OUT'); ReWrite(Output); For p:=1 to A-1 do Begin q:=A-p; If p*q=B then Begin WriteLn(p, ' ', q); Break; End; End; Close(Output); End.

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

DẠ

Y

M

- 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 ‟1234567891011‟  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) => „234567891011‟  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) => „34567891011‟  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) thì xóa 1 chữ số cuối là số 1 (chênh lệch giữa k và biến Dem), cuối cùng xuất kết quả là 911 Trang 21

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

FI CI A

{$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ó

L

Lập trình như sau:

ƠN

// Nối các số 1, 2, 3, …, n vào chuổi Ch Ch:=''; For i:=1 to n do Begin Str(i, Ch_i); Ch:=Ch+Ch_i; End;

OF

Begin Assign(Input, 'TROCHOI.INP'); Reset(Input); ReadLn(n, K); Close(Input);

DẠ

Y

M

QU Y

NH

// 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 Assign(Output, 'TROCHOI.OUT'); ReWrite(Output); WriteLn(Ch); Close(Output); End.

Trang 22

Biên soạn: Th.S Nguyễn Anh Việt


Hướng giải quyết:

QU Y

NH

ƠN

OF

FI CI A

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

i-1, j

i, j-1

i, j

i, j+1

i+1, j

DẠ

Y

M

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

- Chỉ đi lên ô trên (i-1) nếu i > 1, xuống khi i < m, qua trái nếu j > 1, qua phải nếu j < n và các ô này có cùng giá trị với ô a[i,j]. Trang 23

Biên soạn: Th.S Nguyễn Anh Việt


FI CI A

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

Lập trình như sau:

QU Y

NH

ƠN

OF

Var m, n, i, j, t, Dem: Integer; a: Array [1..100, 1..100] of Integer; // 10 loai cay {---------------------------------------------------------------------------} Function So_cay(d, c: Integer): Integer; Var Dem_Doc, Dem_Ngang, Luu_d, Luu_c: Integer; // Đếm dọc, ngang, lưu dòng Begin // và cột 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 Assign(Input, 'DICHUYEN.INP'); Reset(Input); ReadLn(m, n, t); For i:=1 to m do For j:=1 to n do Read(a[i,j]); Close(Input); For i:=1 to m do For j:=1 to n do If (a[i,j]>0) and (So_cay(i, j)<t) then Inc(Dem); // Đếm số cây cùng loại

DẠ

Y

M

Assign(Output, 'DICHUYEN.OUT'); ReWrite(Output); WriteLn(Dem); Close(Output); End.

Trang 24

Biên soạn: Th.S Nguyễn Anh Việt


NH

ƠN

OF

FI CI A

Đề 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.

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

Hướng giải quyết:

QU Y

- Nhận xét: Dãy số 1, 2, 4, 7, 11, 16, 22, … chính là dãy số 1+0=1, 1+1=2, 2+2=4, 4+3=7, 7+4=11, 11+5=16, 16+6=22, … - Tạo mảng a như sau:  a[1]=1  a[2]=a[1]+1  a[3]=a[2]+2 …  a[i]=a[i-1]+i

M

Lập trình như sau:

Var a: Array [1..1000000] of QWord; n, i: LongInt;

DẠ

Y

Begin Assign(Input, 'CSTN.INP'); Reset(Input); ReadLn(n); Close(Input); a[1]:=1; For i:=2 to n do a[i]:=a[i-1]+i-1;

Trang 25

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

ƠN

OF

FI CI A

L

Assign(Output, 'CSTN.OUT'); ReWrite(Output); Write(a[n]); Close(Output); End.

Hướng giải quyết:

QU Y

NH

- Có 2 cách xử lý bài này - Cách thứ nhất: Dùng vòng For i:=1 to n, xét số chữ số của i để cộng vào biến đếm (Dem)  Từ 1..9: Có 1 chữ số  Từ 10..99: Có 2 chữ số … - 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: Var n, i: LongInt; // n<=109 Dem: QWord;

M

Begin Assign(Input, 'DDDS.INP'); Reset(Input); ReadLn(n); Close(Input);

DẠ

Y

For i:=1 to n do Case i of 1..9: Dem:=Dem+1; // Số i có 1 chữ số 10..99: Dem:=Dem+2; // Số i có 2 chữ số 100..999: Dem:=Dem+3; // ... 1000..9999: Dem:=Dem+4; 10000..99999: Dem:=Dem+5; 100000..999999: Dem:=Dem+6; 1000000..9999999: Dem:=Dem+7;

Trang 26

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

FI CI A

L

10000000..99999999: Dem:=Dem+8; 100000000..999999999: Dem:=Dem+9; 1000000000: Dem:=Dem+10; End; Assign(Output, 'DDDS.OUT'); ReWrite(Output); WriteLn(Dem); Close(Output); End.

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

2

3

4

5

6

0..9 10

0..99 190

0..999 2,890

0..9999 38,890

0..99999 488,890

0..999999 5,888,890

7

NH

1

ƠN

OF

- 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ố  Từ 100..999 có (999-100+1=900) số, mỗi số có 3 chữ số => có 900x3=2700 chữ số Vậy từ 0..999 có 190+2700=2890 chữ số … - Chúng ta có bảng thống kê như sau: 0..9999999 68,888,890

8

9

10

0..99999999 788,888,890

0..999999999 8,888,888,890

0..9999999999 98,888,888,890

QU Y

- Tạo mảng TK ứng với bảng thống kê trên theo công thức:  TK[1]=10  TK[2] = (99-10+1)*2+TK[1]  TK[2] = ((102-1)-101+1)*2+TK[1]  TK[3] = (999-100+1)*3+TK[2]  TK[2] = ((103-1)-102+1)*2+TK[2]

M

Do đó TK[i] =((10i+1-1)-10i+1)*i+TK[i-1] với i lấy giá trị từ 2..10 - Đếm số chữ số từ 1 đến 23.456:  Chúng ta thấy 23.456 < 99999 = 105-1 => chọn giá trị TK[5-1]=TK[4]=38.890  Từ 0..9999 có TK[4] = 38.890 chữ số  Từ 10.000 đến 23.456 có (23.456-10000+1=13.457) số, mỗi số có 5 chữ số => có 13.457x5=67.285 chữ số Vậy thì từ 0..23.456 có (38.890+67.285=106.175) chữ số.  Từ 1..23.456 có (106.175-1=106.174) chữ số.

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

DẠ

Y

Var n, i: LongInt; TK: Array [1..10] of QWord; LT10, Dem: QWord; Begin

Trang 27

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

FI CI A

L

Assign(Input, 'DDDS.INP'); Reset(Input); ReadLn(n); Close(Input); TK[1]:=10; LT10:=10; // Tạo mảng thống kê TK For i:=2 to 10 do Begin TK[i]:=((LT10*10-1)-LT10+1)*i + TK[i-1]; LT10:=LT10*10; End;

OF

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; Dec(i); LT10:=LT10 div 10;

DẠ

Y

M

QU Y

NH

ƠN

Assign(Output, 'DDDS.OUT'); ReWrite(Output); Dem:=(n-LT10+1)*(i+1)+TK[i]; WriteLn(Dem-1); Close(Output); End.

Trang 28

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

NH

Begin Assign(Input, 'DONNHAT.INP'); Reset(Input); ReadLn(n); For i:=1 to n do Read(a[i]); Close(Input);

ƠN

Lập trình như sau: Var n, i, j: Integer; a: Array [1..1000] of LongInt; DonNhat: Boolean;

FI CI A

OF

- 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

L

Hướng giải quyết:

QU Y

DonNhat:=True; For i:=1 to n-1 do For j:=i+1 to n do If a[i]=a[j] then Begin DonNhat:=False; Break; End;

DẠ

Y

M

Assign(Output, 'DONNHAT.OUT'); ReWrite(Output); If DonNhat then Write(1) else Write(0); Close(Output); End.

Trang 29

Biên soạn: Th.S Nguyễn Anh Việt


Hướng giải quyết:

QU Y

NH

ƠN

OF

FI CI A

Đề 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.

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

- 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 được số có giá trị lớn - Dùng vòng For i:=1 to Length(n) downto 1 để in ra số đảo ngược của số n

Var n: String; i: Integer;

M

Lập trình như sau:

Y

Begin WriteLn('Ban hay nhap so n'); ReadLn(n); // Đọc số n theo dạng chuổi (String) để dễ xử lý

DẠ

For i:=Length(n) downto 1 do Write(n[i]); End.

Trang 30

Biên soạn: Th.S Nguyễn Anh Việt


FI CI A

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

Hướng giải quyết:

ƠN

OF

- 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ố)

NH

Lập trình như sau:

M

QU Y

Var PhanSo, TuSo, MauSo: String; TS, MS, UC: LongInt; VT, Loi: Integer; {--------------------------------------------------------------------} Function UCLN(a, b: LongInt): LongInt; 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'); ReadLn(PhanSo);

DẠ

Y

VT:=Pos('/', PhanSo); TuSo:=Copy(PhanSo, 1, VT-1); MauSo:=Copy(PhanSo, VT+1, Length(PhanSo)-VT); Val(TuSo, TS, Loi); Val(MauSo, MS, Loi); UC:=UCLN(TS, MS); TS:=TS div UC;

Trang 31

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

OF

FI CI A

L

MS:=MS div UC; WriteLn(TS, '/', MS); End.

Hướng giải quyết:

Lập trình như sau:

QU Y

Begin WriteLn('Nhap so n'); ReadLn(n);

NH

Var So, Loi, n, i, j, L, Luu_i: LongInt; Tong: QWord; Ch: String;

ƠN

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

M

i:=1; L:=1; Tong:=1; While L<n do Begin Inc(i); Luu_i:=i; Str(i, Ch); For j:=1 to Length(Ch) do Begin Val(Ch[j], So, Loi); Tong:=Tong+So; Inc(L); If L=n then Break; // Nếu chữ số cộng vào là thứ n thì ngưng End; End;

DẠ

Y

WriteLn(Tong); End.

Trang 32

Biên soạn: Th.S Nguyễn Anh Việt


Hướng giải quyết:

QU Y

NH

ƠN

OF

FI CI A

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

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

i, j+1

i+1, j

i+1, j+1

DẠ

Y

M

1, 1

Trang 33

m-1, n-1

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2

Lập trình như sau:

OF

Var Max: Byte; a: Array [1..1000, 1..1000] of Byte; Dem: Array [1..255] of Byte; // Do các a[i,j]<=255 m, n, i, j: Integer; Begin Assign(Input, 'HinhVuong.Inp'); Reset(Input);

NH

ƠN

ReadLn(m, n); For i:=1 to m do For j:=1 to n do Read(A[i, j]); Close(Input);

FI CI A

L

- 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

QU Y

For i:=1 to m-1 do For j:=1 to n-1 do If (a[i,j]=a[i+1,j]) and (a[i,j]=a[i,j+1]) and (a[i,j]=a[i+1,j+1]) then Inc(Dem[a[i,j]]); Max:=Dem[1]; For i:=2 to 255 do If Max<Dem[i] then Max:=Dem[i];

M

Assign(Output, 'HinhVuong.Out'); ReWrite(Output); WriteLn(Max); Close(Output); End.

DẠ

Y

Hết tập 2 ---------------------------ooOoo---------------------------

Trang 34

Biên soạn: Th.S Nguyễn Anh Việt


Hướng giải quyết:

QU Y

NH

ƠN

OF

FI CI A

Đề thi Tin học trẻ tỉnh Kon Tum năm 2015 Khối Trung học Cơ sở Thời gian làm bài: 150 phút.

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

Y

M

- Khi cắt lần 1, có thể cắt theo chiều đứng (Đ) hay chiều ngang (N) vì đều chia bánh ra làm 2 phần, nên chúng ta chọn chiều đứng, vết cắt là Đ1:

DẠ

- Khi cắt lần 2, nếu cắt theo chiều đứng chúng ta chỉ được 3 phần, trong khi cắt theo chiều ngang (số phần tối đa được cắt là 2), sẽ chia bánh ra làm 4 phần, nên chúng ta chọn chiều ngang, vết cắt là N2:

Trang 1

Biên soạn: Th.S Nguyễn Anh Việt


OF

FI CI A

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

QU Y

NH

ƠN

- Khi cắt lần 3, có thể cắt theo chiều đứng (Đ) hay chiều ngang (N) vì đều chia bánh ra làm 6 phần (số phần tối đa được cắt là 2), nên chúng ta chọn chiều đứng, vết cắt là Đ3:

DẠ

Y

M

- Khi cắt lần 4, nếu cắt theo chiều đứng chúng ta chỉ được 8 phần, trong khi cắt theo chiều ngang (số phần tối đa được cắt là 3) sẽ chia bánh ra làm 9 phần, nên chúng ta chọn chiều ngang, vết cắt là N4:

Từ đây, chúng ta thấy rằng muốn cắt bánh để được số phần nhiều nhất phải theo qui luật sau đây: Trang 2

Biên soạn: Th.S Nguyễn Anh Việt


OF

FI CI A

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

ƠN

- Từ đây chúng ta thấy có qui luật: Nếu số lần cắt k là số chẵn (2, 4, 6, 8), số phần tối đa sau khi cắt sẽ là số phần tối đa theo mỗi chiều bình phương (22=4, 32=9, 42=16, 52=25); nếu số lần cắt k là số lẻ (1, 3, 5, 7), số phần tối đa sau khi cắt sẽ là số phần tối đa theo mỗi chiều x (số phần tối đa theo mỗi chiều – 1) (2x1=2, 3x2=6, 4x3=12, 5x4=20)

NH

- Ngoài ra, chúng ta có thể thấy rằng nếu k là số chẵn (2, 4, 6, 8), số phần tối đa theo 2 chiều sẽ là (k+2)/2: thí dụ như (2+2)/2=4, (4+2)/2=3, (6+2)/2=4, (8+2)/2=5. Nếu k là số lẻ (1, 3, 5, 7), số phần tối đa theo 2 chiều sẽ là (k+3)/2: thí dụ như (1+3)/2=2, (3+3)/2=3, (5+3)/2=4, (7+3)/2=5. Cuối cùng chúng ta tìm được công thức cho kết quả: ((n+2)/2)2

n lẻ:

((n+3)/2) * ((n+3)/2-1)

Lập trình như sau: Var k: QWord;

QU Y

n chẵn:

M

Begin Assign(Input, 'CatBanh.Inp'); Reset(Input); ReadLn(k); Close(Input);

Assign(Output, 'CatBanh.Out'); ReWrite(Output);

DẠ

Y

If k mod 2=0 then Write(SQR((k+2) div 2)) // Số lần cắt là số chẵn else Write(((k+3) div 2)*((k+3) div 2-1)); // Số lần cắt là số lẻ Close(Output); End.

Trang 3

Biên soạn: Th.S Nguyễn Anh Việt


OF

FI CI A

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

ƠN

Hướng giải quyết:

Bội của i, đánh dấu 0 4, 6, 8, 10, 12, 14, 16 6, 9, 12, 15 4, 8, 12, 16

Ghi chú Các số này không là số nguyên tố Các số 6, 12 đã được đánh dấu 0 từ i=2 Các số 4, 8, 12, 16 đã được đánh dấu 0

QU Y

i 2 3 4

NH

- Do giới hạn của a[i] là 108 nên chúng ta phải dùng sàng nguyên tố Eratosthen để giải quyết bài toán. TD: Với Input như trên thì số lớn nhất của dãy số là SLN_DaySo=17: Dùng mảng SNT[1..SLN_DaySo] để đánh dấu các số nguyên tố. Đầu tiên cho toàn bộ mảng bằng 1, riêng SNT[1]=0 vì 1 không là số nguyên tố Chạy vòng for i từ 2 đến căn bậc 2 của 17 (cắt bỏ số lẻ là 4), nếu SNT[i]=1 thì đánh dấu các bội số của i là 0 ta thu được kết quả:

Cuối cùng, chỉ còn lại các số nguyên tố được đánh dấu 1 là 2, 3, 5, 7, 11, 13 và 17

DẠ

Y

M

Như vậy, nếu SNT[i]=1 thì i là số nguyên tố, ngược lại i không là số nguyên tố - Cách tìm ước số chung lớn nhất của 2 số, Thí dụ : a=12 và b=18 a = a mod b = 12 mod 18 = 12, giữ nguyên b=18 Đổi giá trị a và b => a =18, b=12 a = a mod b = 18 mod 12 = 6, giữ nguyên b=12 Đổi giá trị a và b => a=12, b=6 a = a mod b = 12 mod 6 = 0, giữ nguyên b=6 Đổi giá trị a và b => a=6, b=0 Đến khi b=0 thì ngưng, kết quả chính là a=6 - Sau khi đọc vào dãy số, dùng 2 vòng for i:=1 to n-1 và for j:=i+1 to n để xét tất cả các cặp số a[i] và a[j], nếu USCLN của a[i] và a[j] là số nguyên tố (SNT[USCLN(a[i], a[j])]=1) thì tăng biến đếm

Trang 4

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

L

Lập trình như sau:

M

QU Y

NH

ƠN

OF

FI CI A

{$M 11000000} // Tăng cường bộ nhớ Var n, i, j, Dem, SLN_DaySo: LongInt; SNT :array [1..10000000] of byte; // i là số nguyên tố thì SNT[i]=1 a :array [1..107] of byte; // n<=100, nên khai báo dư một chút {--------------------------------------------------------------------} Function USCLN(a, b: LongInt): LongInt; Var Tmp :LongInt; Begin While b>0 do begin a:=a mod b; tmp:=a; a:=b; b:=tmp; // Đổi giá trị a và b end; Exit(a); End; {--------------------------------------------------------------------} Procedure Eratosthene(N:longint); Var i,j :LongInt; Begin Fillchar(SNT,sizeof(SNT),1); SNT[1]:=0; For i:=2 to Trunc(SQRT(N)) do If SNT[i]=1 then begin // Tìm các bội số của i<=N và gán là 0 j:=i*i; While j<=N do begin SNT[j]:=0; j:=j+i; End; End; End; {====================================================================} Begin Assign(Input, 'NTo.Inp'); Reset(Input); ReadLn(n); SLN_DaySo:=0; For i:=1 to n do Begin Read(a[i]); If SLN_DaySo<a[i] then SLN_DaySo:=a[i]; // Tìm số lớn nhất của dãy End; Close(Input);

DẠ

Y

Eratosthene(SLN_DaySo); For i:=1 to n-1 do For j:=i+1 to n do If SNT[USCLN(a[i], a[j])]=1 then Inc(Dem); Assign(Output, 'NTo.Out'); ReWrite(Output); WriteLn(Dem); Close(Output); End.

Trang 5

Biên soạn: Th.S Nguyễn Anh Việt


ƠN

OF

FI CI A

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

Hướng giải quyết:

QU Y

NH

- Xét dãy số trung bình 1 2 2 3 4, vì số 1 là trung bình cộng của chính nó (a[1]/1) nên dãy số a sẽ có a[1]/1=b[1], tức là a[1]=b[1] - Số thứ 2 là b[2]=(a[1]+a[2])/2 => a[1]+a[2]=2 x b[2] = 4 => a[2] = 2*b[2] - a[1] = a[2] = 2*b[2] - b[1] - Số thứ 3 là b[3]=(a[1]+a[2]+a[3])/3 => a[1]+a[2]+a[3]=3*b[3] => a[3] = 3*b[3] – (a[1]+a[2]) , mà (a[1]+a[2])/2=b[2] nên a[1]+a[2]=2*b[2] => a[3] = 3*b[3] – 2*b[2] - Số thứ 4 là b[4]=(a[1]+a[2]+a[3]+a[4])/4 => a[1]+a[2]+a[3]+a[4]=4*b[4] => a[4] = 4*b[4] – (a[1]+a[2]+a[3]) , mà (a[1]+a[2]+a[3])/3=b[3] nên a[1]+a[2]+a[3]=3*b[3] => a[4] = 4*b[4] – 3*b[3] - Vậy số thứ i sẽ là a[i] = i*b[i] – (i-1)*b[i-1] - Tóm lại ta có: a[1]=b[1], a[i] = i*b[i] – (i-1)*b[i-1] với i=2 đến n

M

Lập trình như sau:

{$M 11000000} Var n, i: LongInt; // n<= 105 a, b :array [1..100007] of LongInt; // a[i] <= 109

DẠ

Y

Begin Assign(Input, 'SumAvr.Inp'); Reset(Input); ReadLn(n); For i:=1 to n do Read(b[i]); Close(Input); a[1]:=b[1]; For i:=2 to n do a[i]:=i*b[i] - (i-1)*b[i-1];

Trang 6

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

NH

ƠN

OF

FI CI A

L

Assign(Output, 'SumAvr.Out'); ReWrite(Output); For i:=1 to n do Write(a[i], ' '); Close(Output); End.

Hướng giải quyết:

M

QU Y

- Số bút chì cần mua là 36, mua 5 tặng 1 sẽ nhận được 6. Lấy 36/6=6 lần mua, nhưng thực tế chỉ cần mua 5 chiếc bút chì mỗi lần với giá là 5 nên số tiền cần trả là 6*5*5=150 - Trường hợp số bút chì cần mua không chia hết cho 6, thí dụ như 38 thì số lần mua được ưu đãi là 38 div 6 = 6 lần và số bút chì mua không được tặng thêm là 38 mod 6 = 2. Số tiền cần trả là 6*5*5 + 5*2 = 150 + 10 = 160 - Vậy với n là số bút chì cần mua, k là số bút chì mua sẽ được tặng thêm 1 và p là giá mỗi chiếc bút, chúng ta có công thức: Số tiền trả = n div (k+1) * p * k + (n mod (k+1)) * p = p * ( (n div(k+1) * k) + n mod (k+1) ) = 5 * (6*5 + 2) = 160

Lập trình như sau:

{$M 11000000} Var n, k, p: QWord; // n, k, p <= 109

Y

Begin Assign(Input, 'SALE.Inp'); Reset(Input); ReadLn(n , k, p);

DẠ

Assign(Output, 'SALE.Out'); ReWrite(Output); Write( p * ( n div (k+1) * k + n mod (k+1) ) ); Close(Output); End.

Trang 7

Biên soạn: Th.S Nguyễn Anh Việt


Hướng giải quyết:

QU Y

NH

ƠN

OF

FI CI A

Đề thi Tin học trẻ tỉnh Trà Vinh năm 2018 Khối Trung học Cơ sở Thời gian làm bài: 120 phút.

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

DẠ

Y

M

- Trường hợp n=15: Xét số xuất phát là 15 div 2 = 7 => 7+8=15 => ngưng (Cách 1) Giảm số xuất phát 1 là 6 => 6+7=13, 6+7+8=21 > 15 => ngưng Giảm số xuất phát 1 là 5 => 5+6=11, 5+6+7= 18 => ngưng Giảm số xuất phát 1 là 4 => 4+5=9, 4+5+6=15 => ngưng (Cách 2) Giảm số xuất phát 1 là 3 => 3+4=7, 3+4+5=12, 3+4+5+6=18 => ngưng Giảm số xuất phát 1 là 2 => 2+3=5, …, 2+3+4+5=14, 2+3+4+5+6=20 => ngưng Giảm số xuất phát 1 là 1 => 1+2=3, …, 1+2+3+4+5=15 => ngưng (Cách 3) - Tóm lại, dùng vòng For i:=n div 2 downto 1, cộng dồn các số j từ i, i+1, i+2, … vào biến tổng (Tong) trong khi Tong<n. Nếu Tong=n thì đây là một cách phân tích n thành tổng các số nguyên liên tiếp Trang 8

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

L

Lập trình như sau:

OF ƠN

Begin Write('Nhap n: '); Readln(n); Dem:=1; For i:=n div 2 downto 1 do Begin Tong:=0; j:=i; While Tong<n do Begin Tong:=Tong+j; j:=j+1; End; If Tong=n then Begin Write('Cach ', Dem, ': '); For k:=i to j-1 do Write(k, ' '); Inc(Dem); WriteLn; End; End;

FI CI A

Var n, i, j, k, Tong, Dem:integer;

DẠ

Y

M

QU Y

NH

If Dem=1 then Writeln('Khong the bieu dien'); ReadLn; End.

Trang 9

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

Hướng giải quyết:

FI CI A

L

- Dùng 2 vòng For i:=1 to n-1 (để có số phía sau) và For j:=i+1 to n để duyệt qua tất cả các cặp số a[i] và a[j]. Nếu a[i]+a[j]=k thì xuất ra kết quả là vị trí I và j.

Lập trình như sau: Var a: array[1..100] of integer; n, k, i, j: Integer; Co_KQ: Boolean;

OF

Begin Assign(Input,'Sum.Inp'); Reset(Input); ReadLn(n, k); For i:=1 to n do Read(a[i]); Close(Input);

ƠN

Co_KQ:=False; // Cần chạy trước đoạn này để biết có kết quả hay không For i:=1 to n-1 do For j:=i+1 to n do If a[i]+a[j]=k then Begin Co_KQ:=True; Break; End;

DẠ

Y

M

QU Y

NH

Assign(Output,'Sum.Out'); ReWrite(Output); If Co_KQ then Begin // Nếu có, xuất các kết quả WriteLn('Vi tri 2 goi co tong bang ',k); For i:=1 to n-1 do For j:=i+1 to n do If a[i]+a[j]=k then WriteLn(i,' va ',j); End Else Write(0); Close(Output); End.

Trang 10

Biên soạn: Th.S Nguyễn Anh Việt


Hướng giải quyết:

QU Y

NH

ƠN

OF

FI CI A

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

Y

M

- Sử dụng hàm Copy(Chuổi, vị trí, số ký tự), TD: Copy(‘ABCD’, 2, 3)=’BCD’ - Viết hàm Xoay(Chuổi Ch, vị trí VT), thí dụ như chuổi ABCD: Nếu VT=1, kết quả là chuổi ABCD => Copy(Ch,1,4)+ Copy(Ch,1,0) Nếu VT=2, kết quả là chuổi BCDA => Copy(Ch,2,3)+ Copy(Ch,1,1) Nếu VT=3, kết quả là chuổi CDAB => Copy(Ch,3,2)+ Copy(Ch,1,2) Nếu VT=4, kết quả là chuổi DABC => Copy(Ch,4,1)+ Copy(Ch,1,3) Do đó, kết quả của hàm là Ch_KQ=Copy(Ch,VT,Length(Ch)+1-VT)+ Copy(Ch,1,VT-1) - Viết hàm Palin(Chuổi Ch) trả về True nếu Ch là chuổi Palindrom hay False nếu ngược lại, TD: Ch=’ABCBA’, ký tự 1 sẽ được so sánh với ký tự 5 (đều là A), ký tự 2 so sánh với ký tự 4 (đều là B). Số lần so sánh là Length(Ch) div 2=2. Ký tự thứ i sẽ được so sánh với ký tự thứ Length(Ch)+1-i. Chỉ cần có một sự khác nhau thì hàm trả về False.

DẠ

Lập trình như sau: Var Ch: String; i: Integer; Co_KQ: Boolean; {--------------------------------------------------------------------}

Trang 11

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

ƠN

OF

FI CI A

L

Function Xoay(Ch: String; VT: Integer): String; Var Ch_KQ: String; i: Integer; Begin Ch_KQ:=Copy(Ch,VT, Length(Ch)-VT+1); Ch_KQ:=Ch_KQ+Copy(Ch,1,VT-1); Exit(Ch_KQ); Exit(Ch_KQ); End; {--------------------------------------------------------------------} Function Palin(Ch: String): Boolean; Var i: Integer; Begin For i:=1 to Length(Ch) div 2 do If Ch[i] <> Ch[Length(Ch)+1-i] then Exit(False); Exit(True); End; {====================================================================} Begin Assign(Input,'Palin.Inp'); Reset(Input); ReadLn(Ch); Close(Input);

NH

Co_KQ:=False; // Cần chạy trước đoạn này để biết có kết quả hay không For i:=1 to Length(Ch) do If Palin(Xoay(Ch, i)) then Begin Co_KQ:=True; Break; End;

DẠ

Y

M

QU Y

Assign(Output,'Palin.Out'); ReWrite(Output); If Co_KQ then // Có kết quả, xuất giá trị 1 Write(1) Else Write(0); Close(Output); End.

Trang 12

Biên soạn: Th.S Nguyễn Anh Việt


DẠ

Y

M

QU Y

NH

ƠN

OF

FI CI A

Đề thi Tin học trẻ tỉnh An Giang năm 2021 Khối Trung học Cơ sở Thời gian làm bài: 150 phút.

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

Trang 13

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

L

Hướng giải quyết: n=5 7 3 8 2 4

8 1 7 5

0 4 2

4 6

FI CI A

- Việc đọc dữ liệu input khó hơn bình thường, cần phải phân tích: Mảng a[] 11 21 22 31 32 33 41 42 43 44 51 52 53 54 55

5

OF

Dòng 1 đọc 1 số, dòng 2 đọc 2 số, …, dòng n đọc n số => lập trình như sau: For i:=1 to n do For j:=1 to i do Read(a[i, j]);

QU Y

NH

ƠN

- Do chỉ có thể đi xuống trái và xuống phải, nên mỗi phần tử chỉ có thể được đi từ trên trái hoặc trên phải:

- Lập bảng qui hoạch động Q để tìm giá trị lớn nhất khi đi từ đỉnh của tam giác như sau: Q[1,1]=a[1,1]

M

Q[d,c]=Max(Q[d-1,c-1], Q[d-1,c]) + a[d,c] với dòng d = 2..n và cột c-1 hay c phải thỏa điều kiện >=1 và <= d vì dòng d chỉ có d cột.

Chúng ta có bảng Q như sau: 7

3

8 5

8

1

7

Y

2 4

7 10 0 4

2

18 4

6

20 5

24

15 16

25 30

15 20

27

19 26

24

DẠ

- Truy vết tìm đường đi

Trang 14

Xác định vị trí của Max dòng 5: [5,2] => VT_Cot_Max=2

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

L

Cho biến dòng d=n (5), biến cột c=VT_Cot_Max (2)

7 1

8 5

0 4

7

4

10

2

6

16

18 4

20 5

24

15

25

15

20

27

30

19

26

24

OF

2

7 8

3

FI CI A

Tìm vị trí của số lớn nhất trong 2 số Q[d-1, c-1] và Q[d-1, c] (20 và 25) và xác định vị trí, chúng ta được kết quả:

Lập trình như sau:

M

QU Y

NH

ƠN

Var n, d, c, Max, VT_Cot_Max: Integer; a, Q: Array [0..1005, 0..1005] of Integer; Ch, Chuoi_KQ: String; {--------------------------------------------------------------------} Procedure QHD; // Quy hoạch động Begin Q[1,1]:=a[1,1]; For d:=2 to n do For c:=1 to d do Begin Max:=Q[d-1,c-1]; // Max của Ô trên, trái If Max<Q[d-1,c] then Max:=Q[d-1,c]; // và ô trên Q[d,c]:=Max+a[d,c]; // cộng với a[d,c] hiện tại End; End; {--------------------------------------------------------------------} Procedure TruyVet; Begin Max:=Q[n,1]; VT_Cot_Max:=1; For c:=1 to d do If Max<Q[n,c] then Begin Max:=Q[n,c]; VT_Cot_Max:=c; End;

DẠ

Y

c:=VT_Cot_Max; While d>=1 do Begin Str(a[d,c], Ch); Chuoi_KQ:=Ch + ' ' + Chuoi_KQ; If Q[d-1,c-1]>Q[d-1,c] then Dec(c); // Nếu ô trên, trái lớn:giảm cột Dec(d); End; End; {====================================================================} Begin Assign(Input, 'Bai01.Inp'); Reset(Input);

Trang 15

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

L

ReadLn(n);

FI CI A

For d:=1 to n do For c:=1 to d do Read(a[d, c]); Close(Input); QHD; TruyVet;

Hướng giải quyết:

QU Y

NH

ƠN

OF

Assign(Output, 'Bai01.Out'); ReWrite(Output); WriteLn(Max); WriteLn(Chuoi_KQ); Close(Output); End.

M

- Sử dụng mảng Chon[] để chọn các số từ dãy số 4 2 5 1 6 8 3, TD: Khi Chon={1, 0, 1, 0, 1, 1, 1} tương ứng với các số 4+2+5+6+8+3 = 26

- Mỗi vị trí VT sẽ có giá trị là 0 hay 1, xuất phát từ vị trí 1 (Try(1)) và kết thúc khi vị trí bằng n (If VT=n then _Print) là đã chọn được một bộ các số. Nếu tổng của nó bằng S=26 thì in kết quả.

DẠ

Y

- Khi Chon[VT]=1 thì số a[VT] được chọn, tổng sẽ cộng vào a[VT] (Tong:=Tong+Chon[VT]*a[VT]). Gọi đệ quy Try(VT+1) để thử VT kế tiếp. Khi quay lại thì trừ giá trị a[VT] ra khỏi tổng (Tong:=Tong-Chon[VT]*a[VT]) - Trong quá trình chọn tiếp tục các vị trí kế tiếp, nếu tổng vẫn còn <= S (Tong <= S) thì mới thử vị trí kế tiếp để loại bỏ các nhánh không có kết quả nếu đi tiếp các vị trí phía sau, giúp cho chương trình chạy nhanh hơn (If Tong <= S then Try(VT+1)). Trang 16

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

L

Lập trình như sau:

FI CI A

Var n, i, S, Tong: Integer; Co_KQ: Boolean; a, Chon: Array [1..33] of Integer;

{--------------------------------------------------------------------} Procedure _Print; Var i: Integer; Begin // đã chọn (Chon[i]=1)

Co_KQ:=True; For i:=1 to n do

If Chon[i]=1 then Write(a[i], ' ');

OF

If Tong=S then Begin // In ra các dãy số có tổng = S tại các vị trì

ƠN

WriteLn; End; End;

{--------------------------------------------------------------------} Var j: Integer; Begin Chon[VT]:=j;

QU Y

For j:=0 to 1 do Begin

NH

Procedure Try(VT: Integer); // Thử tại ví trí VT

Tong:=Tong+a[VT]*Chon[VT];

// Nếu chọn, cộng a[VT] vào tổng

If VT=n then _Print

else If Tong<=S then Try(VT+1); // Thử ví trí kế VT+1 nếu tổng<=S Tong:=Tong-a[VT]*Chon[VT];

// Trừ ra a[VT] nếu trước đó có chọn

M

End; End; Begin

{====================================================================} Assign(Input, 'Bai02.Inp'); Reset(Input);

Y

ReadLn(n, S);

DẠ

For i:=1 to n do Read(a[i]); Close(Input);

Trang 17

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

L

Assign(Output, 'Bai02.Out'); ReWrite(Output);

FI CI A

Try(1);

If not Co_KQ then Write('khong co day con co tong bang ', S); Close(Output);

DẠ

Y

M

QU Y

NH

ƠN

OF

End.

Trang 18

Biên soạn: Th.S Nguyễn Anh Việt


M

QU Y

NH

ƠN

OF

Thời gian làm bài: 150 phút

FI CI A

Đề thi Tin học trẻ TP. Vinh 2019 Khối Trung học Cơ sở

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

Hướng giải quyết:

- Trong quá trình đọc file input ktra.inp, nếu đếm số phần tử bằng 0 vượt quá phân nửa số phần tử của ma trận (=số dòng x số cột) => ma trận thưa hoặc số phần tử khác 0 bằng phân nửa số phần tử => không phải ma trận thưa thì ngưng đọc và kết luận tính chất của ma trận

Y

Lập trình như sau:

DẠ

Var

sd, sc, d, c, Dem_0, Dem_khac_0: Integer; a: Array [1..2000, 1..2000] of Integer;

Trang 19

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

L

Begin Assign(Input, 'ktra.inp');

FI CI A

Reset(Input); ReadLn(sd, sc); For d:=1 to sd do For c:=1 to sc do Begin Read(a[d, c]);

OF

If a[d, c]=0 then Inc(Dem_0) else Inc(Dem_khac_0);

If (Dem_0>(sd*sc) / 2) or (Dem_khac_0>=(sd*sc) / 2) then Break; // Nếu số phần tử (PT) 0 vượt hơn nửa số phần tử của

Close(Input);

// ma trận hay số PT <> 0 >= số PT => ngưng

ƠN

End;

Assign(Output, 'ktra.out');

NH

ReWrite(Output);

If Dem_0>(sd*sc) / 2 then Write('Dung la ma tran thua') else Write('Sai, khong la ma tran thua'); Close(Output);

DẠ

Y

M

QU Y

End.

Trang 20

Biên soạn: Th.S Nguyễn Anh Việt


NH

ƠN

OF

FI CI A

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

Hướng giải quyết:

- Đầu tiên, đọc file Input2.Int để lấy ra các từ gốc vào mảng Goc[] và các từ thay thế vào mảng The[]:

QU Y

Dùng hàm Pos() để tìm vị trí của khoảng trắng ‘_‘ trong chuổi ‘ban_em’ => Pos=4

Từ gốc sẽ là chuổi con lấy từ vị trí 1 đến Pos()-1=3 => ‘ban’ Từ thay thế là chuổi con lấy từ vị trí Pos()+1=5 với độ dài là Length(‘ban_em’) - Pos() = 6-4=2 => ‘em’

M

Biếm đếm (Dem) sẽ cho biết số từ cần thay thế (có 2 từ là ‘ban’ và ‘cao’)

- Tiếp tục đọc từng dòng của file Input1.int vào biến string Ch, dùng vòng For i chạy từ 1 đến Dem, nếu hàm Pos(Goc[i], Ch)>0 nghĩa là có từ Goc[i] trong dòng này, TD: Ch=’chao cac ban’, Goc[1]=’ban’, => Pos()=10

Y

Xóa Chuổi Ch tại vị trí Pos()=10, số ký tự cần xóa là Length(Goc[i])=3 => ‘chao cac ‘

DẠ

Chen chuổi thay thế The[i]=’em’ vào chuổi Ch tại vị trí Pos => ‘chao cac em’

Lập trình như sau: Trang 21

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

L

Var Ch, Ch_Goc, Ch_The: String;

FI CI A

Goc, The: Array [1..55] of String; Dem, VT, i: Integer; Begin Assign(Input, 'Input2.int'); Reset(Input); Dem:=0;

OF

While not EOF() do Begin // Đọc các cặp từ tìm và thay thế ReadLn(Ch); Inc(Dem);

Ch_Goc:=Copy(Ch,1,Pos(' ', Ch)-1); // Tách từ ‘bạn_em’

ƠN

Ch_The:=Copy(Ch,Pos(' ', Ch)+1, Length(Ch)-Pos(' ', Ch)); Goc[Dem]:=Ch_Goc; End; Close(Input); Assign(Input, 'Input1.int');

QU Y

Reset(Input);

NH

The[Dem]:=Ch_The;

Assign(Output, 'KQ.out'); ReWrite(Output);

While not EOF() do Begin

ReadLn(Ch); // Đọc mỗi dòng For i:=1 to Dem do

M

If Pos(Goc[i], Ch)>0 then Begin VT:=Pos(Goc[i], Ch); // Tìm vị trí từ ‘bạn’

Delete(Ch, VT, Length(Goc[i])); // Xóa từ ‘bạn’ Insert(The[i], Ch,

VT); // Chen vào từ ‘em’

End;

Y

WriteLn(Ch); End;

DẠ

Close(Input); Close(Output);

End.

Trang 22

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

FI CI A

- Đầu tiên, viết Function NT(n: Integer): Boolean để xét số nguyên tố

L

Hướng giải quyết: - Chỉ cần dùng 2 vòng For x:=2 to n (do 2 là số nguyên tố nhỏ nhất) và For y:=x to n (do y>=x) để tìm bộ 3 số nguyên tố, vì tổng của 3 số là n nên số thứ ba sẽ là n-x-y và n-xy>=y để tránh lặp lại các kết quả. Nếu x và y và n-x-y là nguyên tố thì xuất kết quả

Lập trình như sau: Var

OF

n, x, y: Integer;

{--------------------------------------------------------------------} Function NT(n: Integer): Boolean; Var i: Integer;

ƠN

Begin

If n<2 then Exit(False); // Các số <2 không là số nguyên tố For i:=2 to Trunc(SQRT(n)) do // Thử xem n có chia hết 2..căn(n) If n mod i=0 then Exit(False); // Chia hết -> không là nguyên tố

NH

Exit(True); // Không chia hết cho số nào -> nguyên tố End;

{====================================================================} Begin Reset(Input); Read(n); Close(Input);

QU Y

Assign(Input, 'TimNghiem.int');

M

Assign(Output, 'TimNghiem.Out'); ReWrite(Output);

For x:=2 to n do

For y:=x to n do If NT(x) and NT(y) and NT(n-x-y) and (n-x-y>=y) then WriteLn(x, ' ', y, ' ', n-x-y);

Y

WriteLn('0 0 0';

DẠ

Close(Output);

End.

Trang 23

Biên soạn: Th.S Nguyễn Anh Việt


M

QU Y

NH

ƠN

OF

Thời gian làm bài: 150 phút

FI CI A

Đề thi Tin học trẻ TP. Vị Thanh 2019 Khối Trung học Cơ sở

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

Hướng giải quyết:

Y

- Đầu tiên, sắp thứ tự 3 số a1, a2, a3 tăng dần:

DẠ

Nếu a1>a2: t=a1, a1=a2; a2=t;

Trang 24

Nếu a1>a3: t=a1, a1=a3; a3=t; Nếu a2>a3: t=a2, a2=a3; a3=t; Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

L

- Chúng ta thu được kết quả: a1=123, a2=234, a3=345

FI CI A

- Chuyển 3 giá trị thành chuổi Ch1=’123’, Ch2=’234’, Ch3=’345’

- Kết quả dãy không giảm sẽ là Ch1+Ch2, Ch1+Ch3, Ch2+Ch1, Ch2+Ch3, Ch3+Ch1, Ch3+Ch2 lần lượt là: ‘123234’, ‘123345’, 234123’, ‘234345’, ‘345123’, ‘345234’

Lập trình như sau: Var a1, a2, a3, t: LongInt;

OF

Ch1, Ch2, Ch3: String; Begin WriteLn('Nhap a1');

ƠN

ReadLn(a1); WriteLn('Nhap a2'); ReadLn(a2);

NH

WriteLn('Nhap a3'); ReadLn(a3);

If a1>a2 then Begin t:=a1; a1:=a2; a2:=t; End; // Sắp thứ tự tăng If a1>a3 then Begin t:=a1; a1:=a3; a3:=t; End;

QU Y

If a2>a3 then Begin t:=a2; a2:=a3; a3:=t; End; Str(a1, Ch1); // Đổi số thành chuổi Str(a2, Ch2);

M

Str(a3, Ch3);

WriteLn(Ch1+Ch2,' ',Ch1+Ch3,' ',Ch2+Ch1,' ',Ch2+Ch3,' ',Ch3+Ch1,' ', Ch3+Ch2); // ReadLn;

DẠ

Y

End.

Trang 25

Biên soạn: Th.S Nguyễn Anh Việt


OF

FI CI A

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

Hướng giải quyết:

ƠN

- Tìm chuổi đảo của chuổi Ch=‘abcded’ => ChDao=‘dedcba’

- Lập bảng quy hoạch động Q[] để tìm chuổi con dài nhất của Ch và ChDao: Dòng 0 bằng 0

NH

Cột 0 bằng 0

Dòng 1 đến dòng n=Length(Ch)=6, với biến d là dòng và biến c là cột: . Nếu ChDao[d]=Ch[c] => Q[d, c]=Q[d-1, c-1]+1 (Q[ô trên, trái] + 1) trên) Q[]

1 a 0 0 0 0 0 0 1

M

ChDao d e d c b a

0 1 2 3 4 5 6

0 Ch 0 0 0 0 0 0 0

QU Y

. Ngược lại, Q[d, c]=Max(Q[d, c-1], Q[d-1, c] (ô lớn nhất giữa ô trái và ô

2 b 0 0 0 0 0 1 1

3 c 0 0 0 0 1 1 1

4 d 0 1 1 1 1 1 1

5 E 0 1 2 2 2 2 2

6 d 0 1 2 3 3 3 3

DẠ

Y

- Truy vết d=n=6; c=n=6; while (d>1) - Lui dòng đến khi Q[d,c]<>=3, lui cột đến khi !=3 - Ghi nhận ký tự chung là d - c giảm 1 (cột c= 2) Trang 26

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

L

Kết quả dãy con chung là ded

FI CI A

- Tìm chuổi đối xứng Ba ký tự cần thêm là a, b và c Ký tự đầu chuổi Ch là a => thêm a vào cuối Ch a

b

c

d

e

d

a

Bỏ qua 2 ký tự đầu và cuối b

c

d

e

d

b

c

d

e

d

OF

Ký tự thứ hai cần thêm là b bằng ký tự đầu => thêm vào cuối chuổi Ch b

Bỏ qua 2 ký tự đầu và cuối d

e

d

ƠN

c

Ký tự thứ ba cần thêm là c bằng ký tự đầu => thêm vào cuối chuổi Ch c

d

e

d

a

b

c

d

Lập trình như sau: Var

e

NH

Cuối cùng kết quả là

c

d

c

b

a

QU Y

Ch, ChDao, ChChen, KyTuChen: String; n, i, d, c, VT, VT_Tim: Integer;

Q: Array [0..25, 0..25] of Integer; Chon: Array [0..25] of Integer;

{--------------------------------------------------------------------}

M

Function Max(a, b: Integer): Integer; Begin End;

If a>b then Exit(a) else Exit(b); {--------------------------------------------------------------------} Procedure QHD;

Y

Begin

DẠ

For d:=0 to n do Q[d,0]:=0; // Cột 0 bằng 0 For c:=0 to n do Q[0,c]:=0; // Dòng 0 bằng 0 For d:=1 to n do

Trang 27

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

If ChDao[d]=Ch[c] then Q[d,c]:=Q[d-1,c-1]+1 // [Ô trên, trái]+1

FI CI A

else Q[d,c]:=Max(Q[d,c-1], Q[d-1,c]); // Max(ô trái, ô trên)

L

For c:=1 to n do

End;

{--------------------------------------------------------------------} Procedure TruyVet; Begin While (d>1) and (c>1) and (Q[d,c]>0) do Begin While (Q[d,c]=Q[d-1,c]) do Dec(d); Chon[d]:=1; while (Q[d,c]=Q[d,c-1]) do Dec(c);

ƠN

If c>1 then Dec(c); End;

NH

ChChen:='';

OF

d:=n; c:=n;

For i:=1 to n do

If Chon[i]=0 then ChChen:=ChChen+ChDao[i]; // Tạo chuổi chen = ‘abc’

QU Y

VT:=1; While ChChen<>'' do Begin

While Ch[VT]=Ch[Length(Ch)+1-VT] do Inc(VT); VT_Tim:=1;

While (ChChen[VT_Tim]<>Ch[VT]) and (ChChen[VT_Tim]<>Ch[Length(Ch)+1VT]) do // Tìm ký tự chen tương ứng với đầu hay cuối chuổi

M

Inc(VT_Tim);

KyTuChen:=ChChen[VT_Tim]; Delete(ChChen, VT_Tim, 1);

If Ch[VT]=KyTuChen then Insert(KyTuChen,Ch,Length(Ch)+2-VT) // Chen cuối chuổi else If Ch[Length(Ch)+1-VT]=KyTuChen then

Y

Insert(KyTuChen, Ch, VT); // Chen đầu chuổi Inc(VT);

DẠ

End;

WriteLn(Ch);

End;

Trang 28

Biên soạn: Th.S Nguyễn Anh Việt


L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

{====================================================================}

FI CI A

Begin WriteLn('Nhap xau S: '); ReadLn(Ch); n:=Length(Ch); For i:=n downto 1 do

OF

ChDao:=ChDao+Ch[i]; QHD; TruyVet;

ƠN

// ReadLn;

DẠ

Y

M

QU Y

NH

End.

Trang 29

Biên soạn: Th.S Nguyễn Anh Việt


ƠN

OF

FI CI A

L

BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

Hướng giải quyết:

- Nếu N mod A=0 thì kết quả chính là N, TD: N=120, A=8 => ‘120 chia het cho 8’

NH

- Trường hợp N mod A<>0, chúng ta lấy N div A. TD: N=123, A=8, 123 div 8=15, sau đó lấy số này nhân với A, 15 x 8 = 120, chênh lệch là (123-120=3). Tuy nhiên với n=127 và A=8 thì cách làm này cho kết quả là 120 và chênh lệch là (127-120=7). Nhưng nếu chúng ta lấy số 128 cũng chia hết cho 8 nhưng chênh lệch là (128-127=1).

Lập trình như sau:

QU Y

- Do đó chúng ta sẽ tạo ra 2 số cùng chia hết cho A là (N div A) * A và ((N div A)+1) * A. Số nào có chênh lệch với N nhỏ hơn sẽ được chọn để xuất kết quả.

Var N, N1, N2: LongInt; A: Integer;

M

Begin Write('Nhap N: ');

ReadLn(N);

Write('Nhap A: ');

Y

ReadLn(A);

// Số nhỏ chia hết cho A

DẠ

N1:=(N div A)*A;

N2:=((N div A)+1)*A; // Số lớn chia hết cho A

Trang 30

Biên soạn: Th.S Nguyễn Anh Việt


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 3

L

If abs(N-N1)<abs(N-N2) then Write(N1, ' chia het cho ', A) // Xuất N1 else Write(N2, ' chia het cho ', A); // Xuất N2

FI CI A

// ReadLn; End.

DẠ

Y

M

QU Y

NH

ƠN

OF

Hết tập 3 ---------------------------ooOoo---------------------------

Trang 31

Biên soạn: Th.S Nguyễn Anh Việt


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.