Tải bản đầy đủ (.pdf) (22 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 1

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 (891.72 KB, 22 trang )

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

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

-

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


-

Với n=7,

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

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.

Chương trình viết trên Free Pascal 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)
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);
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.


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

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


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

// Dem


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

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

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]


Chương trình viết như sau:
{$H+}
Var
n, k, i: Integer;
A, Ch: String;
Begin
Assign(Input, 'So.Inp');
Reset(Input);
Read(n, k);
Close(Input);
A:='';
For i:=1 to n do Begin
Str(i, Ch); A:=A+Ch;
End;
Assign(Output, 'So.Out');
ReWrite(Output);
WriteLn(A);
WriteLn(A[k]);

Close(output);
End.


Đề thi Tin học trẻ huyện Hoa Lư năm 2018
Khối Trung học Cơ sở
Thời gian làm bài: 120 phút.

Hướng giải quyết:
 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


Chương trình viết như sau:
Const MaxN=10000;
Var n, k, i, j, vt: Integer;
A: Array [1..MaxN] of LongInt; t: LongInt;
Begin
Assign(Input,'XepCay.Inp'); Reset(Input);
ReadLn(n);
For i:=1 to n do Read(A[i]);
ReadLn(k);

// 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;
// Tim vi tri de chen so k
vt:=1;
While (k>A[vt]) and (vtIf vt=n then Inc(vt);
// Xuat ket qua
Assign(Output, 'DaySo.Out'); ReWrite(Output);
For i:=1 to n do Write(A[i], ' '); WriteLn;
Write(vt);
Close(Output);
End.


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

 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

M
B

C

Xb


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

{-----------------------------------------------------}
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);

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



Hướng giải quyết:
 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

Chương trình viết như sau:
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



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


Đề thi Tin học trẻ TP. Qui Nhơn 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:
 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:
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);


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.

Hướng giải quyết:
 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ố:
''

'10'

''


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

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


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


Hướng giải quyết:

 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:
Uses SysUtils; // Dung ham trim
Var Ch, ChTB: String; Min, Max, Tong, n: LongInt;
Begin
Assign(Input, 'DuLieu.Inp'); Reset(Input);
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 MaxEnd;
Close(Input);
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.


Hướng giải quyết:


-

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:
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,'DaySo.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]);
Assign(Output,'DaySo.Out'); ReWrite(Output);
WriteLn(BC);
Close(Output);
End.


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

Hướng giải quyết:
 Đố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 (*)

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

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


End;
{=====================================================}
Begin
Assign(Input,'NgTo.Inp'); Reset(Input);
Read(k); Close(Input);
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:
 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.


 Chương trình viết như sau:
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 MaxEnd;
// 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.


Hướng giải quyết:
 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.


Chương trình viết như sau:
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]);
Assign(Output,'DenNhay.Out'); ReWrite(Output);
WriteLn(BC);
Close(Output);
End.



×