Tải bản đầy đủ (.pdf) (34 trang)

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

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.35 MB, 34 trang )

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

Đề 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:
 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
- 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;
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);
While not EOF() do Begin
ReadLn(n);
Dem:=0;
So:=10;
While Dem

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


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


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2
// 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;
// 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;
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.

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

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 2

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:
 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
 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 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 (dIf (c>1) and (a[d,c-1]=v01) and (DD[d,c-1]=False) then Loang(d,c-1,v01);
If (cEnd;
{====================================================================}

Begin
Assign(Input, 'VUNG.INP');
Reset(Input);
ReadLn(n, m);
For i:=1 to n do
For j:=1 to m do
Read(a[i,j]);
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


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

Đề 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ố 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ập trình như sau:
Var
i, sd, sc: Integer;
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.

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


BÀI GIẢI ĐỀ THI TIN HỌC TRẺ CÁC TỈNH, QUẬN, HUYỆN, THỊ XÃ – Tập 2
- Đế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;
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;

Assign(Output, 'RANDOM.INP');
ReWrite(Output);
For i:=1 to n do Write(a[i], ' ');
Close(Output);
// 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);
// 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
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


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

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;
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 DemInc(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
End;
Exit(i);
End;
{--------------------------------------------------------------------}
Begin
Assign(Input, 'TD.INP');
Reset(Input);
ReadLn(a, b);
Close(Input);
Assign(Output, 'TD.UOP');
ReWrite(Output);
If a=b then Begin Write(1); Close(Output); Exit; End;
If aLuu_a:=a;
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;
If NTTD then Write(1) else Write(0);
Close(Output);
End.

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

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 2

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ự  Lần 1:
Pos(‘12’ ,‘12bbb11122544466bbRb’)=1 | Dem_1=1 | => ‘--bbb11122544466bbRb’

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

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

- 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ập trình như sau:
Var
P, Luu_P, k1, k2: String;
i, Dem_1, Dem_2, VT: Integer;
Begin
Assign(Input, 'MAHOA.INP');
Reset(Input);
ReadLn(P); ReadLn(k1); ReadLn(k2);
Luu_P:=P;
Close(Input);
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;
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;
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


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

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

Lập trình như sau:
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);
Assign(Output, 'UC.OUT');
ReWrite(Output);
WriteLn(UC);
Close(Output);
End.

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 2

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

Lập trình như sau:
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;
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
Close(Input);
// Đề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);
// 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.

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

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 2

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

Lập trình như sau:
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;
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);
// 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ừ
// Đá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;
// 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;
// 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


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

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

Lập trình như sau:
Var
A, B, p, q: Integer;
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



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

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.

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

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ó
Begin
Assign(Input, 'TROCHOI.INP');
Reset(Input);
ReadLn(n, K);
Close(Input);
// 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;
// Xóa k số để thu được số lớn nhất
L:=Length(Ch); Dem:=0; i:=1;
While (i < L-1) and (DemCo_Lon_Hon:=False;
For j:=i+1 to L do
If Ch[i]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


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

i, j-1

i, j

i, j+1

i+1, 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


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:
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 (dd:=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 (cIf 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)Assign(Output, 'DICHUYEN.OUT');
ReWrite(Output);
WriteLn(Dem);
Close(Output);
End.

Trang 24

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

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

- 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

Lập trình như sau:
Var
a: Array [1..1000000] of QWord;
n, i: LongInt;
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