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 (d
If (c>1) and (a[d,c-1]=v01) and (DD[d,c-1]=False) then Loang(d,c-1,v01);
If (c
End;
{====================================================================}
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 Dem
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
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 a
Luu_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 (Dem
Co_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 (d
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
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)
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