You are on page 1of 72

Tuyểể n chọọ n mọộọ t sọố bàà i tọàá n tin cơ bàả n

Giới thiệu
Trong tài liệu này tuyển chọn một số bài toán tin cơ bản ở nhiều nguồn khác nhau. Nó thường xuất
hiện trong các kỳ thi học sinh giỏi các cấp.
Các bài tập trong tài liệu này tương đối đơn giản. Không sử dụng bất kỳ một thuật toán đặc biệt (đệ
quy – quay lui, quy hoạch động, tham lam …) nào, mỗi bài có thể có nhiều cách giải khác nhau.
Nhằm mục đích ôn lại các loại cấu trúc dữ liệu đơn giản và mối tương quan giữa các cấu trúc này.
Nhằm hình thành tư duy lập trình bước đầu cho bạn đọc.
Để có thể tham khảo tốt nhất về tài liệu này các bạn cần đọc thêm kiến thức về chương trình con,
nhập xuất dữ liệu bằng tệp văn bản.
Nếu cảm thấy thú vị các bạn có thể tham khảo thêm một số tài liệu sau:
o Tuyển chọn 100 bài tập lập trình cơ bản (code pascal và c++).
o Tuyển chọn 50 bài toán đệ quy – quay lui – vét cạn (code pascal và c++).
o Tuyển chọn 50 bài toán quy hoạch động (code pascal và c++).
o Tuyển chọn 50 toán đồ thị (code pascal và c++).
o Tuyển chọn 20 bài toán về cấu trúc dữ liệu đặc biệt.

Pàgể 1
Tuyểể n chọọ n mọộọ t sọố bàà i tọàá n tin cơ bàả n

Cấu trúc cơ bản, If…Then…Else


Bài 1: Chữ số
Viết chương trình cho biết chữ số hàng nghìn, hàng trăm, hàng chục, hàng đơn vị của một số có 4
chữ số.
Dữ liệu vào: Lưu trong tệp ChuSo.inp một số nguyên dương có 4 chữ số.
Dữ liệu ra: Ghi vào tệp ChuSo.out có cấu trúc như ví dụ dưới đây.
Ví dụ:
ChuSo.inp ChuSo.out
1234 Chu so hang nghin: 1
Chu so hang tram: 2
Chu so hang chuc: 3
Chu so hang don vi: 4
Chương trình:
Program ChuSo;
Var fi,fo: text;
n,Nghin,Tram,Chuc,DonVi:integer;
Begin
assign(fi,'ChuSo.inp');
reset(fi);
read(fi,n);
close(fi);
Nghin:=n div 1000; n:=n mod 1000;
Tram:=n div 100; n:=n mod 100;
Chuc:=n div 10; DonVi:=n mod 10;
assign(fo,'ChuSo.out');
rewrite(fo);
writeln(fo,'Chu so hang nghin: ',Nghin);
writeln(fo,'Chu so hang tram:' ,Tram);
writeln(fo,'Chu so hang chuc: ',Chuc);
writeln(fo,'Chu so hang don vi: ',DonVi);
close(fo);
End.
Bài 2: Hình chữ nhật
Tính diện tích và chu vi hình chữ nhật
4
Dữ liệu vào: Lưu trong tệp Hcn.inp hai số nguyên dương (≤10 ) thể hiện chiều dài và chiều
rộng của hình chữ nhật.
Dữ liệu ra: Ghi vào tệp Hcn.out chu vi và diện tích hình chữ nhật.
Ví dụ:
Hcn.inp Hcn.out
5 6 22 30
Chương trình:
Program HCN;
Var fi,fo:text;
a,b,CV,Dt:
longint;
Begin
assign(fi,'Hcn.inp');

Pàgể 2
reset(fi);
read(fi,a,b);
close(fi);
Dt:=a*b;
Cv:=(a+b)*2;
assign(fo,'Hcn.out');
rewrite(fo);
write(fo,Cv,' ',Dt);
close(fo);
End.
Bài 3: Tam giác
Kiểm tra ba số nguyên có thể tạo thành 3 cạnh của một tam giác hay không? Nếu có thì tính chu vi
và diện tích của tam giác đó.
4
Dữ liệu vào: Lưu trong tệp Tamgiac.inp ba số nguyên dương (≤10 ).
Dữ liệu ra: Ghi vào tệp Tamgiac.out với cấu trúc như sau:
+ Nếu ba số nguyên không tạo thành 3 cạnh của tam giác thì ghi “No”.
+ Nếu tạo thành thì ghi ra chu vi và diện tích của tam giác.
Ví dụ:
Tamgiac.inp Tamgiac.out
2 3 4 9 2.90
Tamgiac.inp Tamgiac.out
2 3 6 No
Chương trình:
Program Tamgiac;
Var fi,fo: text;
a,b,c,CV:
longint; Dt,p:
real;
Kt: boolean;
Begin
assign(fi,'Tamgiac.inp');
reset(fi);
read(fi,a,b,c);
close(fi);
if (a+b>c)and(b+c>a)and(c+a>b)then Kt:=true else Kt:=false;
if (kt=true) then
Begin
Cv:=a+b+c;
p:=Cv/2;
Dt:=sqrt(p*(p-a)*(p-b)*(p-c));
End;
assign(fo,'Tamgiac.out');
rewrite(fo);
if (Kt=false) then write(fo,'No');
if (Kt=true) then write(fo,Cv,' ',Dt:4:2);
close(fo);
End.
Bài 4: Phương trình bậc hai.
2
Tìm nghiệm của phương trình bậc hai ax +bx+c=0 (a≠0).
Dữ liệu vào: Lưu trong tệp Ptb2.inp 3 số thực lần lượt là 3 hệ số a,b,c.
Dữ liệu ra: Ghi vào tệp Ptb2.out với cấu trúc như sau:
+ Ghi “Ptvn” nếu phương trình vô nghiệm.
+ Ghi hai nghiệm x1, x2 (nếu là nghiệm kép thì ghi hai lần).
Ví dụ:
Ptb2.inp Ptb2.out
2 3 4 Ptvn
Ptb2.inp Ptb2.out
2 4 2 -1.00 -1.00
Ptb2.inp Ptb2.out
3 9 6 -1.00 -2.00
Chương trình:
Program Ptb2;
Var fi,fo: text;
a,b,c,Delta:
longint; x1,x2:
real;
Begin
assign(fi,'Ptb2.inp');
reset(fi);
read(fi,a,b,c);
close(fi);
Delta:=b*b-4*a*c;
if(Delta>=0) then
Begin
x1:=(-b+sqrt(Delta))/(2*a);
x2:=(-b-sqrt(Delta))/(2*a);
End;
assign(fo,'Ptb2.out');
rewrite(fo);
if (Delta<0) then write(fo,'Ptvn');
if (Delta>=0) then write(fo,x1:4:2,' ',x2:4:2);
close(fo);
End.
Bài 5: Karaoke
Một điểm kinh doanh dịch vụ KARAOKE mở cửa từ 9h00 đến 23h00 tất cả các ngày trong
tuần. Cách thức tính tiền của điểm KARAOKE này như sau:
+ Từ thứ 2 đến thứ 6: Từ 9h00 đến 14h00 giá 40.000đ/1 giờ, từ 14h00 đến 23h00 giá
50.000đ/1 giờ. Nếu khách hàng sử dụng nhiều hơn 3 giờ thì mỗi giờ tiếp theo sau giờ thứ 3 được
giảm giá 30% so với đơn giá.
+ Thứ 7, Chủ nhật: Giá 60.000đ/1 giờ.
Dữ liệu vào: Lưu trong tệp karaoke.inp với cấu trúc:
+ Dòng thứ nhất: Lưu một số nguyên duy nhất nằm trong phạm vi từ 2 đến 8 cho biết là
ngày thứ mấy trong tuần (từ thứ hai đến chủ nhật).
+ Dòng thứ hai: Lưu 2 số nguyên nằm trong phạm vi từ 9 đến 23. Số nguyên thứ nhất cho
biết giờ bắt đầu sử dụng dịch vụ, số nguyên thứ hai cho biết giờ kết thúc sử dụng dịch vụ. Hai số
nguyên cách nhau một khoảng trắng và số nguyên thứ hai luôn lớn hơn số nguyên thứ nhất.
Dữ liệu ra: Lưu vào tệp karaoke.out 1 số nguyên duy nhất cho biết số tiền khách hàng phải trả để
sử dụng dịch vụ.
Yêu cầu: Viết chương trình nhập dữ liệu từ tệp karaoke.inp và ghi kết quả ra tệp
karaoke.out. Ví dụ:
karaoke.inp karaoke.out
5 148000
9 13
Giải thích: 148000 = (3*40000)+ (1*40000-1*30%*40000)
Chương trình:
Program Karaoke;
Var
fi,fo: text;
gbd,gkt,thu,tg: byte;
tien:longint;
Begin
assign(fi,'karaoke.inp');
reset(fi);
readln(fi,thu);
readln(fi,gbd,gkt);
close(fi);
tg:=gkt-gbd;
if (thu>=2) and (thu<=6) then
Begin
if gkt<=14 then
if tg<=3 then tien:=tg*40000
else tien:=3*40000+(tg-3)*28000;
if gbd>=14 then
if tg<=3 then tien:=tg*50000
else tien:=3*50000+(tg-3)*35000;
if (gkt>14) and (gbd<14) then
begin
if tg<=3 then tien:=(14-gbd)*40000
+(gkt-14)*50000;
if (14-gbd)>=3 then tien:=3*40000+(14-gbd-3)*28000
+(gkt-14)*35000;
if (14-gbd)<3 then
Begin
if (14-gbd)=1 then tien:=40000+2*50000
+(gkt-14-2)*35000;
if (14-gbd)=2 then tien:=40000*2+50000
+(gkt-14-1)*35000;
End;
End;
End;
if (thu=7) or(thu=8) then tien:=tg*60000;
assign(fo,'karaoke.out');
rewrite(fo);
write(fo,tien);
close(fo);
End.
Bài 6. Xếp Loại
Cách xếp loại học lực của học sinh dựa vào điểm trung bình môn (Tbm) như sau.
+ Tbm ≥ 8 : Xếp loại “Gioi”
+ 6.5 ≤ Tbm < 8 : Xếp loại “Kha”
+ 5 ≤ Tbm < 6.5 : Xếp loại “TrungBinh”
+ Tbm < 5 : Xếp loại “Yeu”
Yêu cầu: Cho biết điểm Tbm hãy xếp loại học lực của học sinh.
Dữ liệu vào: Lưu trong tệp Xeploai.inp một số thực duy nhất cho biết điển Tbm (0 ≤ Tbm ≤ 10).
Dữ liệu ra: Ghi vào tệp Xeploai.out kết quả xếp loại học lực của học sinh.
Ví dụ:
Xeploai.inp Xeploai.out
8.5 Gioi
Chương trình:
Program Xeploai;
Var fi,fo: text;
Tbm: real;
Xeploai:
string;
Begin
assign(fi,'XepLoai.inp');
reset(fi);
read(fi,Tbm);
close(fi);
if (Tbm>=8)then Xeploai:='Gioi'
else if (Tbm>=6.5) then Xeploai:='Kha'
else if (Tbm>=5) then Xeploai:='TrungBinh'
else Xeploai:='Yeu';
assign(fo,'XepLoai.out');
rewrite(fo);
write(fo,Xeploai);
close(fo);
End.
Bài 7. Tiền điện
Công ty điện lực Việt Nam đưa ra bảng giá tiền điện tiêu dùng như sau:
+ 100 Kw đầu giá 1000/1kw
+ 100 Kw tiết theo giá 2000/1kw
+ Các Kw tiếp theo giá 3000/1kw
Yêu cầu: Cho biết chỉ số điện kế tháng trước và chỉ số điện kế tháng này. Tính tiền điện tiêu dùng
phải trả trong tháng.
4
Dữ liệu vào: Lưu trong tệp Tiendien.inp gồm 2 số nguyên dương (<10 ) thể hiện chỉ số điện kế của
tháng trước và tháng này.
Dữ liệu ra: Ghi vào tệp TienDien.out số tiền phải trả trong tháng.
Ví dụ:
TienDien.inp TienDien.out
1 202 303000
Giải thích: Số điện đã sử dụng là 201 Kw thì tiền điện phải trả là:
100*1000+100*2000+1*3000=303000 (đ)
Chương trình:
Program TienDien;
Var fi,fo: text;
a,b,SoDien,Tien:
longint;
Begin
assign(fi,'TienDien.inp');
reset(fi);
read(fi,a,b);
close(fi);
SoDien:=b-a;
if(SoDien>200) then Tien:=100*1000+100*2000+(SoDien-200)*3000
else if(SoDien>100) then Tien:=100*1000+(SoDien-100)*2000
else Tien:=SoDien*1000;
assign(fo,'TienDien.out');
rewrite(fo);
write(fo,Tien);
close(fo);
End.
Bài 8: Trò chơi
Ba bạn Hùng, Dũng, Cường cùng tham gia một trò chơi như sau: Mỗi bạn nắm trong tay
một đồng xu, mỗi đồng xu có hai trạng thái : sấp và ngửa. Theo hiệu lệnh, cả ba bạn cùng đưa đồng
xu của mình ra phía trước. Nếu cả ba đồng xu cùng sấp hoặc cùng ngửa thì chưa phát hiện người
thua cuộc (hòa nhau). Nếu một bạn có trạng thái đồng xu khác với hai bạn kia (nghĩa là đồng xu của
bạn ấy sấp còn hai người kia ngửa và ngược lại đồng xu của bạn ấy ngửa thì hai người kia sấp) thì
bạn đó thắng cuộc. Hãy viết chương cho biết kết quả của trò chơi.
Quy ước: Sấp là 0; ngửa là 1.
Dữ liệu vào: Lưu trong tệp TroChoi.inp 3 số nguyên 0 hoặc 1 cho biết trạng thái đồng xu của 3
bạn theo thứ tự là Hùng, Dũng, Cường.
Dữ liệu ra: Ghi vào tệp TroChoi.out kết quả của trò chơi. Nếu bạn nào thắng thì ghi tên bạn đó,
nếu hòa thì ghi kết quả là “Hoa”.
Ví dụ:
TroChoi.inp TroChoi.out
0 0 0 Hoa
TroChoi.inp TroChoi.out
0 1 0 Dung
Chương trình:
Program TroChoi;
Var fi,fo: text;
Hung,Dung,Cuong:integer;
KetQua:string;
Begin
assign(fi,'TroChoi.inp');
reset(fi);
r
e
a
d
(
f
i
,
H
u
n
g
,
D
u
n
g
,
C
u
o
n
g
)
;
close(fi);
if(Hung=Dung)and(Hung=Cuong) then KetQua:='Hoa';
if(Hung<>Dung)and(Hung<>Cuong) then KetQua:='Hung';
if(Dung<>Hung)and(Dung<>Cuong) then KetQua:='Dung';
if(Cuong<>Hung)and(Cuong<>Dung) then KetQua:='Cuong';
assign(fo,'TroChoi.out');
rewrite(fo);
write(fo,KetQua);
close(fo);
End.
Buà i Họồ ng Dàộ n Pàgể 9
Cấu trúc lặp
Bài 1. Số nguyên tố
Kiểm tra một số có phải là số nguyên tố hay không?
14
Dữ liệu vào: Lưu trong tệp SoNguyenTo.inp một số nguyên dương duy nhất (≤10 ).
Dữ liệu ra: Ghi vào tệp SoNguyenTo.out giá trị Yes hoặc No.
Ví dụ:
SoNguyenTo.inp SoNguyenTo.out
11 Yes
Chương trình:
Program SoNguyenTo;
var n:integer;
Procedure Nhap;
Var fi:text;
Begin
assign(fi,'baitap\50btcb\songuyento.inp');
reset(fi);
read(fi,n);
close(fi);
End;
Function NguyenTo(k:integer):boolean;
Var i:integer;
Begin
i:=1;
repeat
i:=i+1;
until (k mod i =0) or (i*i>k);
if (i*i>k) then NguyenTo:=True else NguyenTo:=False;
End;
Procedure Xuat;
Var fo:text;
Begin
assign(fo,'baitap\50btcb\songuyento.out');
rewrite(fo);
if (Nguyento(n)=true) then write(fo,'Yes')
else write(fo,'No');
close(fo);
End;
Begin
Nhap;
Xuat;
End.
Bài 2: Đảo ngược số
Viết chương trình đảo ngược một số nguyên dương.
18
Dữ liệu vào: Lưu trong tệp DaoNguocSo.inp một số nguyên dương (≤10 ).
Dữ liệu ra: Ghi vào tệp DaoNguocSo.out số đảo ngược.
Ví dụ:
DaoNguocSo.inp DaoNguocSo.out
123456 654321

Buà i Họồ ng Dàộ n Pàgể 9


Chương trình:
Program DaoNguocSo;
Var fi,fo:
text; a:
int64;
Begin
assign(fi,'DaoNguocSo.inp');
reset(fi);
read(fi,a);
close(fi);
assign(fo,'DaoNguocSo.out');
rewrite(fo);
While (a>0) do
Begin
write(fo,a mod 10);
a:=a div 10;
end;
close(fo);
End.
Bài 3: Đổi tiền
Cho một lượng tiền cần đổi và 3 mệnh giá tiền khác nhau. Hãy cho biết có bao nhiêu cách đổi.
Dữ liệu vào: Lưu trong tệp DoiTien.inp có cấu trúc như sau:
6
+ Dòng thứ nhất lưu số tiền cần đổi (≤10 ).
+ Dòng thứ hai lưu 3 mệnh giá tiền.
Dữ liệu ra: Ghi vào tệp DoiTien.out số cách đổi.
Ví dụ:
DoiTien.inp DoiTien.out
200 4
20 30 50
Giải thích: Có 4 cách đổi như sau: (1,1,3)-(1 tờ 20, 1 tờ 30, 3 tờ 50); (2,2,2); (3,3,1); (6,1,1)
Program DoiTien;
Var fi,fo:
text; T:
longint;
a,b,c,dem,i,j,k:integer;
Begin End.

Buà i Họồ ng Dàộ n Pàgể 10


i,a,b,c);
a close(fi);
s dem:=0;
s for i:=1 to (T div a) do
i for j:=1 to (T div b) do
g for k:=1 to (T div c) do
n if(i*a+j*b+k*c=T) then dem:=dem+1;
( assign(fo,'DoiTien.out');
f rewrite(fo);
i write(fo,dem);
, close(fo);
'
D
o
i
T
i
e
n
.
i
n
p
'
)
;

r
e
s
e
t
(
f
i
)
;
r
e
a
d
l
n
(
f
i
,
T
)
;

r
e
a
d
(
f

Buà i Họồ ng Dàộ n Pàgể 11


Bài 4: Tạo hình
Tạo hình với cấu trúc như sau:

*********
********
*******
******
*****
****
***
**
*
4
Dữ liệu vào: Lưu trong tệp Taohinh.inp một số nguyên dương cho biết chiều cao của hình (≤10 ).
Dữ liệu ra: Ghi vào tệp TaoHinh.out hình với chiều cao từ input.
Ví dụ:
TaoHinh.inp TaoHinh.out
5 *****
****
***
**
*
Chương trình:
Program TaoHinh;
Var fi,fo: text;
a,i,j:integer;
Begin
assign(fi,'TaoHinh.inp');
reset(fi);
readln(fi,h);
close(fi);
assign(fo,'TaoHinh.out');
rewrite(fo);
for i:=h downto 1 do
Begin
for j:=1 to i do write(fo,'*');
writeln(fo);
End;
close(fo);
End.
Bài 5: Tạo hình
Tạo hình với cấu trúc như sau:

*
***
*****
*******
**********
************
4
Dữ liệu vào: Lưu trong tệp Taohinh.inp một số nguyên dương cho biết chiều cao của hình (≤10 ).
Dữ liệu ra: Ghi vào tệp TaoHinh.out hình với chiều cao từ input.
Ví dụ:
TaoHinh.inp TaoHinh.out
5 *
***
*****
*******
**********
************
Chương trình:
Program TaoHinh;
Var fi,fo: text;
h,i,j:integer;
Begin
assign(fi,'TaoHinh.inp');
reset(fi);
readln(fi,h);
close(fi);
assign(fo,'TaoHinh.out');
rewrite(fo);
for i:=1 to h do
Begin
for j:=1 to h-i do write(fo,' ');
for j:=1 to i*2-1 do write(fo,'*');
for j:=1 to h-i do write(fo,' ');
writeln(fo);
End;
close(fo);
End.
Bài 6: Ước chung lớn nhất
Tìm ước chung lớn nhất của hai số nguyên dương.
Dữ liệu vào: Lưu trong tệp Ucln.inp hai số nguyên dương.
Dữ liệu ra: Ghi vào tệp Ucln.out ước chung lớn nhất.
Ví dụ:
Ucln.inp Ucln.out
15 25 5
Ghi chú: Ta có thuật toán Euclide tìm UCLN như sau:
UCLN(a,b)={ ( )
( )
Hoặc: Giả sử a=bq+r, với a,b,q,r là các số nguyên thì ta có:

UCLN(a,b)={
( )
BCNN(a,b) = (a*b)/UCLN(a,b)  Cách tính bội chung nhỏ nhất.
Chương trình:
Program UCLN;
Var fi,fo:
text;
a,b:integer;
Begin
assign(fi,'Ucln.inp');
reset(fi);
readln(fi,a,b);
close(fi);
assign(fo,'Ucln.out');
rewrite(fo);
While(a<>b) do
Begin
if(a>b) then a:=a-b;
if(b>a) then b:=b-a;
End;
write(fo,a);
close(fo);
End.
Bài 7: Lũy thừa
30 m
Cho số tự nhiên n (0 < n < 2 ), n luôn được phân tích dưới dạng n= 5 .p trong đó p là số nguyên
dương và m là số tự nhiên lớn hơn hoặc bằng 0.
3
Ví dụ: Với số tự nhiên n = 500 thì n= 5 .4, tức là m = 3, p = 4.
m
Yêu cầu: Tìm tất cả các cặp giá trị m,p thỏa n=5 .p.
Dữ liệu vào: Lưu trong tệp LuyThua.inp với một số tự nhiên thể hiện giá trị n.
Dữ liệu ra: Ghi vào tệp LuyThua.out mỗi dòng ghi một cặp giá trị m,p theo thứ tự tăng dần của p.
Ví dụ:
LuyThua.inp LuyThua.out
500 0 500
1 100
2 20
3 4
Chương trình:
Program LuyThua;
Var n,m,p:longint;
fi,fo:text;
Function Luythua(a:longint;b:byte):longint;
Var i,lt:longint;
Begin
if b=0 then

begin
luythua:=1;
exit;
end;
lt:=1;
for i:=1 to b do
lt:=lt*a;
luythua:=lt;
End;
Begin
assign(fi,'LuyThua.inp');
reset(fi);
readln(fi,n);
close(fi);
assign(fo,'LuyThua.out');
rewrite(fo);
m:=0;
repeat
if(n mod LuyThua(5,m)=0) then
writeln(fo,m,' ',n div LuyThua(5,m));
inc(m);
until(LuyThua(5,m)>n);
close(fo);
End.
Bài 8: Giai thừa
Tính tổng sau: 1+1.2+1.2.3+1.2.3.4+…+1.2.3…(n-1).n
Dữ liệu vào: Lưu trong tệp GiaiThua.inp m ột số tự nhiên n.
Dữ liệu ra: Ghi vào tệp GiaiThua.out tổng các giai thừa.
Ví dụ:
GiaiThua.inp GiaiThua.out
3 9
Chương trình:
Program GiaiThua;
Var n,gt,tong,i,j:longint;
fi,fo:text;
Begin
assign(fi,'GiaiThua.inp');
reset(fi);
readln(fi,n);
close(fi);
gt:=1; tong:=0;
for i:= 1 to n do
Begin
for j:=1 to i do gt:=gt*j;
tong:=tong+gt;
gt:=1;
End;
assign(fo,'GiaiThua.out');
rewrite(fo);
write(fo,tong);
close(fo);
End.
Nhận xét: Ta thấy i! bằng (i-1)!*i từ đó ta có thuật toán độ phức tạp O(n) như sau:
Program GiaiThua;
Var n,gt,tong,i:longint;
fi,fo:text;
Begin
assign(fi,'GiaiThua.inp');
reset(fi);
readln(fi,n);
close(fi);
gt:=1; tong:=0;
for i:= 1 to n do
Begin
gt:=gt*i;
tong:=tong+gt;
End;
assign(fo,'GiaiThua.out');
rewrite(fo);
write(fo,tong);
close(fo);
End.
Mảng một chiều
Bài 1: Max-Min
Cho dãy số gồm n số nguyên. Hãy cho biết độ chênh lệnh giữa phần tử Max và phần tử Min.
Dữ liệu vào: Lưu trong tệp MaxMin.inp có cấu trúc như sau:
7
+ Dòng thứ nhất lưu số nguyên n (n ≤ 10 ) cho biết số phần tử trong dãy.
+ Dòng thứ hai lưu n số nguyên mỗi số cách nhau ít nhất một khoảng trắng.
Dữ liệu ra: Ghi vào tệp MaxMin.out độ chênh lệnh giữa phần tử Max và Min.
Ví dụ:
MaxMin.inp MaxMin.out
5 6
3 5 1 7 4
Chương trình:
Program MaxMin;
Var fi,fo: text;
n,i,Max,Min:integer;
A:array[1..10000000] of longint;
Begin
assign(fi,'MaxMin.inp');
reset(fi);
readln(fi,n);
for i:=1 to n do read(fi,A[i]);
close(fi);
Max:=A[1]; Min:=A[1];
for i:=2 to n do
Begin
if(A[i]>Max) then Max:=A[i];
if(A[i]<Min) then Min:=A[i];
End;
assign(fo,'MaxMin.out')
; rewrite(fo);
write(fo,Max-Min);
close(fo);
End.
Bài 2: Chẵn-Lẻ
Cho dãy số gồm n số nguyên. Hãy cho biết độ chênh lệnh giữa số lượng các phần tử chẵn và số
lượng các phần tử lẻ.
Dữ liệu vào: Lưu trong tệp ChanLe.inp có cấu trúc như sau:
7
+ Dòng thứ nhất lưu số nguyên n (n ≤ 10 ) cho biết số phần tử trong dãy.
+ Dòng thứ hai lưu n số nguyên mỗi số cách nhau ít nhất một khoảng trắng.
Dữ liệu ra: Ghi vào tệp ChanLe.out độ chênh lệnh giữa số lượng chẵn và lẻ.
Ví dụ:
ChanLe.inp ChanLe.out
5 1
2 5 1 7 4
Chương trình:
Program ChanLe;
Var fi,fo: text;
n,i,DemChan,DemLe:integer;
A:array[1..10000000] of longint;
Begin
assign(fi,'ChanLe.inp');
reset(fi);
readln(fi,n);
for i:=1 to n do read(fi,A[i]);
close(fi);
DemChan:=0;
DemLe:=0; for i:=1
to n do
Begin
if(A[i] mod 2=0) then DemChan:=DemChan+1;
if(A[i] mod 2=1) then DemLe:=DemLe+1;
End;
assign(fo,'ChanLe.out');
rewrite(fo);
write(fo,abs(DemChan-DemLe));
close(fo);
End.
Bài 3: Tổng nguyên tố
Cho dãy số gồm n số nguyên. Hãy cho biết tổng của các số nguyên tố trong dãy.
Dữ liệu vào: Lưu trong tệp TongNguyenTo.inp có cấu trúc như sau:
7
+ Dòng thứ nhất lưu số nguyên n (n ≤ 10 ) cho biết số phần tử trong dãy.
+ Dòng thứ hai lưu n số nguyên mỗi số cách nhau ít nhất một khoảng trắng.
Dữ liệu ra: Ghi vào tệp TongNguyenTo.out tổng của các số nguyên tố.
Ví dụ:
TongNguyenTo.inp TongNguyenTo.out
5 14
2 5 1 7 4
Chương trình:
Program TongNguyenTo;
Var fi,fo:
text;
n,i:integer;
Tong:int64;
a:longint;
Function NguyenTo(k:integer):boolean;
Var i:integer;
Begin
i:=1;
repeat
i:=i+1;
until (k mod i=0) or (i*i>k);
if i*i>k then NguyenTo:=True else NguyenTo:=False;
End;
Begin
assign(fi,'TongNguyenTo.inp');
r
e
s
e
t
(
f
i
)
;
read
ln(f
i,n)
;
Tong:=0;
for i:=1 to n do
Begin
read(fi,a);
if(NguyenTo(a)=True) then Tong:=Tong+a;
End;
close(fi);
assign(fo,'TongNguyenTo.out');
rewrite(fo);
write(fo,Tong);
close(fo);
End.
Câu 4: Tần suất
Một dãy số gồm n số nguyên dương A1 A2 A3 … An. Tần suất của một số là số lần suất hiện
của số đó trong dãy.
6
Dữ liệu vào: Lưu trong tệp TanSuat.inp n (n 10 ) số nguyên dương nằm trên một dòng. Mỗi số
5
( Ai 10 ) cách nhau một khoảng trắng.
Dữ liệu ra: Ghi vào tệp TanSuat.out 2 số nguyên mỗi số cách nhau một khoảng trắng. Số thứ nhất
thể hiện số nguyên tố lớn nhất có tần suất lớn nhất, số thứ hai cho biết tần suất của của số nguyên
tố đó.
Yêu cầu: Viết chương trình nhập dữ liệu từ tệp TanSuat.inp và ghi kết quả ra tệp TanSuat.out.
Nếu không có số nguyên tố nào thì ghi hai số 0 mỗi số cách nhau một khoảng trắng.
Ví dụ:
TanSuat.inp TanSuat.out
3 3 3 4 5 5 5 5 6 6 6 7 6 7 6 7 4
6 6 6 7 7 11
Giải thích: Số 5 và số 7 là hai số nguyên tố có tần suất là lớn nhất (4). Nhưng số nguyên tố 7 là số
nguyên tố lớn hơn.
Chương trình:
Program TanSuat;
Var B:array[1..1000000] of longint;
i,max,vt,a,n:longint;
fi,fo:text;
Function NT(c:longint):boolean;
var k:longint;
Begin
k:=1;
repeat
k:=k+1;
until (c mod k =0) or (k*k>c);
if k*k>c then NT:=true else NT:=False;
End;
Begin
Assign(fi,'tansuat.inp');
reset (fi);
while EOF(fi) = false do
Begin
read(fi,a);
if n<a then n:=a;
if nt(a)=true then B[a]:=B[a]+1;
End;
close(fi);
Assign(fo,'tansuat.out');
rewrite(fo);
max:=b[1];
for i:=2 to n do if max <= b[i] then
Begin
max:=b[i];
if max>0 then Vt:=i;
End;
write(fo,vt,' ',max);
close(fo);
End.
Bài 5: Sắp xếp
Cho dãy số gồm n số nguyên. Hãy sắp xếp dãy số theo thứ tự tăng dần.
Dữ liệu vào: Lưu trong tệp SapXep.inp có cấu trúc như sau:
7
+ Dòng thứ nhất lưu số nguyên n (n ≤ 10 ) cho biết số phần tử trong dãy.
+ Dòng thứ hai lưu n số nguyên mỗi số cách nhau ít nhất một khoảng trắng.
Dữ liệu ra: Ghi vào tệp SapXep.out dãy đã được sắp tăng.
Ví dụ:
SapXep.inp SapXep.out
5 1 2 4 5 7
2 5 1 7 4
Chương trình:
Program SapXep;
Var fi,fo: text;
n,i,j:integer;
A:array[1..10000000] of longint;
Procedure DoiCho(var a,b:longint);
Var tam:integer;
Begin
tam:=a;
a:=b;
b:=tam;
End;
Begin
assign(fi,'SapXep.inp');
reset(fi);
readln(fi,n);
for i:=1 to n do read(fi,A[i]);
close(fi);
for i:=1 to n-1 do
for j:=i to n do
if(A[i]>A[j]) then DoiCho(A[i],A[j]);
assign(fo,'SapXep.out');
rewrite(fo);
For i:=1 to n do write(fo,A[i],' ');
close(fo);
End.
Bài 6: Dãy con dương
Cho dãy số gồm n số nguyên. Hãy cho biết số lượng các số dương liên tiếp nhiều nhất.
Dữ liệu vào: Lưu trong tệp DayconDuong.inp có cấu trúc như sau:
7
+ Dòng thứ nhất lưu số nguyên n (n ≤ 10 ) cho biết số phần tử trong dãy.
+ Dòng thứ hai lưu n số nguyên mỗi số cách nhau ít nhất một khoảng trắng.
Dữ liệu ra: Ghi vào tệp DayConDuong.out số lượng các số dương liên tiếp nhiều nhất.
Ví dụ:
DayConDuong.inp DayConDuong.out
8 3
2 5 -1 7 4 3 -2 -2
Chương trình:
Giải thích: Dãy con dương dài nhất là 7 4 3 có độ dài là 3.
Program DayConDuong;
Var fi,fo: text;
n,i,dem,max:integer;
A:array[1..10000000] of longint;
Begin
assign(fi,'DayConDuong.inp');
reset(fi);
readln(fi,n);
for i:=1 to n do read(fi,A[i]);
close(fi);
dem:=0; max:=0;
for i:=1 to n do
Begin
if(A[i]>0) then
Begin
dem:=dem+1;
if(max<dem) then max:=dem;
End;
if(A[i]<=0) then dem:=0;
End;
assign(fo,'DayConDuong.out');
rewrite(fo);
write(fo,max);
close(fo);
End.
Bài 7: Dãy con chẵn
Cho dãy số gồm n số nguyên. Hãy cho biết số lượng các số chẵn liên tiếp nhiều nhất.
Dữ liệu vào: Lưu trong tệp DayconChan.inp có cấu trúc như sau:
7
+ Dòng thứ nhất lưu số nguyên n (n ≤ 10 ) cho biết số phần tử trong dãy.
+ Dòng thứ hai lưu n số nguyên mỗi số cách nhau ít nhất một khoảng trắng.
Dữ liệu ra: Ghi vào tệp DayConchan.out có cấu trúc như sau;
+ Dòng thứ nhất ghi số lượng các số chẵn liên tiếp nhiều nhất.
+ Dòng thứ 2 ghi dãy con chẵn đó (nếu có nhiều dãy bằng nhau thì chỉ ghi dãy đầu tiên).

Buà i Họồ ng Dàộ n Pàgể 20


Ví dụ:
DayConChan.inp DayConChan.out
8 3
2 5 2 2 4 3 -2 -2 2 2 4
Giải thích: Dãy con dương dài nhất là 2 2 4 có độ dài là 3.
Chương trình:
Program DayConChan;
Var fi,fo: text;
n,i,dem,max,vt1,vt2:integer;
A:array[1..10000000] of longint;
Begin
assign(fi,'DayConChan.inp');
reset(fi);
readln(fi,n);
for i:=1 to n do read(fi,A[i]);
close(fi);
dem:=0; max:=0;
for i:=1 to n do
Begin
if(A[i] mod 2=0) then
Begin
dem:=dem+1;
if(max<dem) then
Begin
max:=dem;
vt1:=i-dem+1;
vt2:=i;
End;
End;
if(A[i] mod 2=1) then dem:=0;
End;
assign(fo,'DayConChan.out');
rewrite(fo);
writeln(fo,max);
for i:=vt1 to vt2 do write(fo,A[i],' ');
close(fo);
End.
Bài 8: Dãy con đổi dấu
Cho dãy số gồm n số nguyên. Hãy cho biết dãy số hạng đổi dấu nhiều nhất có bao nhiêu phần tử.
Dữ liệu vào: Lưu trong tệp DayDoiDau.inp có cấu trúc như sau:
7
+ Dòng thứ nhất lưu số nguyên n (n ≤ 10 ) cho biết số phần tử trong dãy.
+ Dòng thứ hai lưu n số nguyên mỗi số cách nhau ít nhất một khoảng trắng.
Dữ liệu ra: Ghi vào tệp DayDoiDau.out số lượng phần tử của dãy đổi dấu nhiều nhất.
Ví dụ:
DayDoiDau.inp DayDoiDau.out
8 3
2 5 -1 7 4 3 -2 -2
Giải thích: Dãy con dương dài nhất là 5 -1 7 có độ dài là 3.

Buà i Họồ ng Dàộ n Pàgể 21


Chương trình:
Program DayDoiDau;
Var fi,fo: text;
n,i,dem,max:integer;
A:array[1..10000000] of longint;
Begin
assign(fi,'DayDoiDau.inp');
reset(fi);
readln(fi,n);
for i:=1 to n do read(fi,A[i]);
close(fi);
dem:=1; max:=0;
for i:=1 to n-1 do
Begin
if(A[i]*A[i+1]<0) then
Begin
dem:=dem+1;
if(max<dem) then max:=dem;
End;
if(A[i]*A[i+1]>0) then dem:=1;
End;
assign(fo,'DayDoiDau.out');
rewrite(fo);
write(fo,max);
close(fo);
End.
Bài 9: Tổng X
Cho dãy số gồm n số nguyên và một số nguyên X. Hãy cho biết dãy số có bao nhiêu cặp phần tử có
tổng bằng X.
Dữ liệu vào: Lưu trong tệp TongX.inp có cấu trúc như sau:
7
+ Dòng thứ nhất lưu hai số nguyên n (n ≤ 10 ) và X.
+ Dòng thứ hai lưu n số nguyên mỗi số cách nhau ít nhất một khoảng trắng.
Dữ liệu ra: Ghi vào tệp TongX.out số lượn các cặp phần tử trong dãy có tổng bằng X.
Ví dụ:
TongX.inp TongX.out
6 10 3
3 7 2 8 4 3
Chương trình:
Program TongX;
Var fi,fo: text;
n,i,j,X,Dem:longint;
A:array[1..10000000] of longint;
Begin
assign(fi,'TongX.inp');
reset(fi);
readln(fi,n,X);
for i:=1 to n do read(fi,A[i]);
close(fi);
Dem:=0;
for i:=1 to n-1 do
for j:=i+1 to n do
if(A[i]+A[j]=X) then inc(Dem);
assign(fo,'TongX.out');
rewrite(fo);
writeln(fo,Dem);
close(fo);
End.
2
Thuật toán trên có độ phức tạp là O(n ). Chúng ta có thể giải bài toán trên với độ phức tạp
O(n) như sau:
Program TongX;
Var fi,fo: text;
n,i,j,X,Dem:longint;
A,B:array[1..10000000] of longint;
Begin
assign(fi,'TongX.inp');
reset(fi);
readln(fi,n,X);
for i:=1 to n do read(fi,A[i]);
close(fi);
for i:=1 to n do inc(B[A[i]]);
Dem:=0;
for i:=1 to n-1 do
if(B[X-A[i]]>0) then
Begin
dem:=Dem+B[A[i]]*B[X-A[i]];
B[A[i]]:=0;
B[X-A[i]]:=0;
End;
assign(fo,'TongX.out');
rewrite(fo);
writeln(fo,Dem);
close(fo);
End.
Mảng 2 chiều
Bài 1: Max Min
Tìm phần tử đạt giá trị Max, và phần tử đạt giá trị Min trong ma trận các số nguyên có kích thước
mxn.
Dữ liệu vào: Lưu trong tệp MaxMinX.inp có cấu trúc như sau:
4
+ Dòng đầu tiên lưu hai số nguyên dương (m,n ≤ 10 ).
+ m dòng tiếp theo mỗi dòng lưu n số nguyên. Mỗi số cách nhau ít nhất một khoảng trắng.
Dữ liệu ra: Ghi vào tệp MaxMin.out có cấu trúc như sau:
+ Dòng thứ nhất ghi phần tử đạt giá trị Max và vị trí của nó.
+ Dòng thứ hai ghi phần tử đạt giá trị Min và vị trí của nó.
+ Nếu có nhiều phần tử đạt giá trị Max hoặc Min thì phần tử Max hoặc Min là phần tử đầu
tiên đạt giá trị Max hoặc Min.
Ví dụ:
MaxMin.inp MaxMin.out
3 4 9 2 4
3 7 2 8 2 1 3
4 5 8 9
2 4 5 6
Giải thích: 9 là phần tử Max vị trí của nó là dòng 2 cột 4.
Chương trình:
Program MaxMin;
Var fi,fo: text;
n,m,i,j,x1,x2,y1,y2:integer;
A:array[1..10000,1..10000] of longint;
Max,Min: longint;
Begin
assign(fi,'MaxMin.inp');
reset(fi);
readln(fi,m,n);
for i:=1 to m do
Begin
for j:=1 to n do read(fi,A[i,j]);
readln(fi);
End;
close(fi);
Max:=A[1,1]; Min:=A[1,1];
For i:=1 to m do
for j:=1 to n do
Begin
if(Max<A[i,j]) then
Begin
max:=A[i,j];
x1:=i; y1:=j;
End;
if(Min>A[i,j]) then
Begin
Min:=A[i,j];
x2:=i; y2:=j;
End;
End;
assign(fo,'MaxMin.out');
rewrite(fo);
writeln(fo,Max,' ',x1,' ',y1);
Write(fo,Min,' ',x2,' ',y2);
close(fo);
End.
Bài 2: Nguyên tố
Đếm trong ma trận các số nguyên có kích thước mxn có bao nhiêu số nguyên tố nằm ở hàng chẵn
đồng thời nằm trên cột lẻ.
Dữ liệu vào: Lưu trong tệp NguyenTo.inp có cấu trúc như sau:
4
+ Dòng đầu tiên lưu hai số nguyên dương (m,n ≤ 10 ).
+ m dòng tiếp theo mỗi dòng lưu n số nguyên. Mỗi số cách nhau ít nhất một khoảng trắng.
Dữ liệu ra: Ghi vào tệp NguyenTo.out số lượng số nguyên tố thỏa điều kiện
Ví dụ:
NguyenTo.inp NguyenTo.out
3 4 2
3 7 2 8
5 5 7 9
2 4 5 6
Giải thích: Có hai số nguyên tố nằm ở hàng chẵn và cột lẻ là 5 (2,1) và 7 (2,3).
Chương trình:
Program NguyenTo;
Var fi,fo: text;
n,m,i,j,Dem:integer;
A:array[1..10000,1..10000] of longint;
Function NguyenTo(k:longint): boolean;
Var i:integer;
Begin
i:=1;
repeat
inc(i);
until (k mod i =0) or (i*i>k);
if i*i<k then NguyenTo:=False else NguyenTo:=True;
End;
Begin
assign(fi,'NguyenTo.inp');
reset(fi);
readln(fi,m,n);
for i:=1 to m do
Begin
for j:=1 to n do read(fi,A[i,j]);
readln(fi);
End;
close(fi);
Dem:=0;
For i:=1 to m do
for j:=1 to n do
if (NguyenTo(A[i,j]))and(i mod 2=0)and(j mod 2=1)
then inc(Dem);
assign(fo,'NguyenTo.out');
rewrite(fo);
write(fo,Dem);
close(fo);
End.
Bài 3: Cực trị
Cho mảng A(n x m) các số nguyên. Phần tử Ai,j với (1 (1  i  n , 1  j  m ) được gọi là phần
tử cực trị nếu nó nhỏ hơn hoặc lớn hơn tất cả các phần tử lân cận với nó.
Dữ liệu vào: Lưu trong tệp CucTri.inp với cấu trúc:
+ Dòng đầu tiên lưu hai số nguyên dương cách nhau một khoảng trắng thể hiện giá trị n và m
(1  n ,m  100 ).
+ n dòng tiếp theo mỗi dòng lưu m số nguyên (-30.000<Ai,j<30.000), mỗi số cách nhau một
khoảng trắng.
Dữ liệu ra: Ghi vào tệp CucTri.out một số nguyên duy nhất thể hiện tổng số phần tử cực trị trong
mảng.
Yêu cầu: Viết chương trình nhập dữ liệu từ tệp CucTri.inp và ghi kết quả ra tệp
CucTri.out. Ví dụ:
CucTri.inp CucTri.out CucTri.inp CucTri.out
3 3 1 3 3 2
3 2 3 3 2 3
2 5 2 1 5 2
3 2 4 3 2 4
Giải thích:
+ Ở ví dụ 1 có 1 cực trị: Số 5 (5>{3,2,3,2,4,2,3,2})
+ Ở ví dụ 2 có 2 cực trị: Số 5 (5>{3,2,3,2,4,2,3,1}) và số 1 (1<{3,2,5,2,3})
Chương trình:
Program CucTri;
Var A:array[1..100,1..100] of integer;
fi,fo:text;
n,m,t,p:integer;
Function KtLanCan(i,j:integer):boolean;
Begin
KtLanCan:=false;
if (i>=1)and(j>=1)and(i<=n)and(j<=m) then
KtLanCan:=true;
End;
Function CucDai(d,c:integer):boolean;
Var i,j:integer;
Begin
CucDai:=true;
for i:=d-1 to d+1 do
for j:=c-1 to c+1 do
if KtLanCan(i,j) then
if (i<>d)or(j<>c) then
if a[i,j] >= a[d,c] then
Begin
CucDai:=false;
End; break;

End;
Function CucTieu(d,c:integer):boolean;
Var i,j:integer;
Begin
CucTieu:=true;
for i:=d-1 to d+1 do
for j:=c-1 to c+1 do
if KtLanCan(i,j) then
if (i<>d)or(j<>c) then
if a[i,j] <= a[d,c] then
Begin
CucTieu:=false;
break;
End;
End;
Procedure XuLy(var t,p:integer);
Var i,j:integer;
Begin
t:=0;
p:=0;
for i:=1 to n do
for j:=1 to m do
Begin
if CucTieu(i,j) then inc(t);
if CucDai(i,j) then inc(p);
End;
End;
Procedure Nhap;
Var i,j:integer;
Begin
assign(fi,'CucTri.inp');
reset(fi);
readln(fi,n,m);
for i:=1 to n do
for j:=1 to m do
read(fi,a[i,j]);
close(fi);
End;
procedure Xuat;
begin
assign(fo,'CucTri.out');
rewrite(fo);
writeln(fo,t+p);
close(fo);
End;
Begin
Nhap;
XuLy(t,p);
Xuat;
End.
Bài 4: Sắp xếp
Cho một ma trận các số nguyên có kích thước nxm. Hãy sắp xếp ma trận tăn dần theo cấu trúc dưới
đây:

Dữ liệu vào: Lưu trong tệp SapXep.inp có cấu trúc như sau:
4
+ Dòng đầu tiên lưu hai số nguyên dương (m,n ≤ 10 ).
+ m dòng tiếp theo mỗi dòng lưu n số nguyên. Mỗi số cách nhau ít nhất một khoảng trắng.
Dữ liệu ra: Ghi vào tệp SapXep.out ma trận sau khi được sắp xếp.
Ví dụ:
SapXep.inp SapXep.out
3 3 1 2 3
1 3 5 4 5 6
4 7 6 7 8 9
8 9 2
Hướng dẫn:
Bước 1: Nhập ma trận từ file SapXep.inp.
Bước 2: Chuyển ma trận thành mảng 1 chiều.
Bước 3: Sắp xếp mảng 1 chiều.
Bước 4: Chuyển mảng 1 chiều thành 2 chiều theo đúng vị trí của từng phần tử.
Bước 5: Ghi ma trận đã được sắp xếp ra file SapXep.out
Chương trình:
Program NguyenTo;
Var fi,fo: text;
n,m,i,j:integer;
k,t:longint;
A:array[1..10000,1..10000] of longint;
B:array[1..100000000] of longint;
Procedure HoanDoi(var a,b: longint);
Var Tam:longint;
Begin
Tam:=a;
a:=b;
b:=Tam;
End;
Procedure Nhap;
Begin
assign(fi,'SapXep.inp');
reset(fi);
readln(fi,m,n);
for i:=1 to m do
Begin
for j:=1 to n do read(fi,A[i,j]);
readln(fi);
End;
close(fi);
End;
Procedure Chuyen1Chieu;
Begin
k:=1;
for i:=1 to m do
for j:=1 to n do
Begin
B[k]:=A[i,j];
k:=k+1;
End;
End;
Procedure SapXep1Chieu;
Begin
for k:=1 to m*n-1 do
for t:=k+1 to m*n do
if B[k]>B[t] then HoanDoi(B[k],B[t]);
End;
Procedure Chuyen2Chieu;
Begin
k:=1;
For i:=1 to m do
for j:=1 to n do
Begin
A[i,j]:=B[k];
k:=k+1;
End;
End;
Procedure Xuat;
Begin
Assign(fo,'SapXep.out');
rewrite(fo);
for i:=1 to m do
Begin
for j:=1 to n do write(fo,A[i,j]:3);
writeln(fo);
End;
close(fo);
End;
Begin
Nhap;
Chuyen1Chieu;
SapXep1Chieu;
Chuyen2Chieu;
Xuat;
End.
Bài 5: Sắp xếp 2
Cho một ma trận các số nguyên có kích thước nxm. Hãy sắp xếp ma trận tăn dần theo cấu trúc dưới
đây:
Dữ liệu vào: Lưu trong tệp SapXep.inp có cấu trúc như sau:
4
+ Dòng đầu tiên lưu hai số nguyên dương (m,n ≤ 10 ).
+ m dòng tiếp theo mỗi dòng lưu n số nguyên. Mỗi số cách nhau ít nhất một khoảng trắng.
Dữ liệu ra: Ghi vào tệp SapXep.out ma trận sau khi được sắp xếp.
Ví dụ:
SapXep.inp SapXep.out
3 3 1 2 3
1 3 5 6 5 4
4 7 6 7 8 9
8 9 2
Hướng dẫn:
Bước 1: Nhập ma trận từ file SapXep.inp.
Bước 2: Chuyển ma trận thành mảng 1 chiều.
Bước 3: Sắp xếp mảng 1 chiều.
Bước 4: Chuyển mảng 1 chiều thành 2 chiều theo đúng vị trí của từng phần tử.
Bước 5: Ghi ma trận đã được sắp xếp ra file SapXep.out.
Chương trình:
Program SapXep;
Var fi,fo: text;
n,m,i,j,Dem:integer;
k,t:longint;
A:array[1..10000,1..10000] of longint;
B:array[1..100000000] of longint;
Procedure HoanDoi(var a,b: longint);
Var Tam:longint;
Begin
Tam:=a;
a:=b;
b:=Tam;
End;
Procedure Nhap;
Begin
assign(fi,'SapXep.inp');
reset(fi);
readln(fi,m,n);
for i:=1 to m do
Begin
for j:=1 to n do read(fi,A[i,j]);
readln(fi);
End;
close(fi);
End;
Procedure Chuyen1Chieu;
Begin
k:=1;
for i:=1 to m do
for j:=1 to n do
Begin

Buà i Họồ ng Dàộ n Pàgể 30


B[k]:=A[i,j];
k:=k+1;
End;
End;
Procedure SapXep1Chieu;
Begin
for k:=1 to m*n-1 do
for t:=k+1 to m*n do
if B[k]>B[t] then HoanDoi(B[k],B[t]);
End;
Procedure Chuyen2Chieu;
Begin
k:=1; i:=1;
While(i<=m) do
Begin
if(i mod 2=1) then
for j:=1 to n do
Begin
A[i,j]:=B[k];
inc(k);
End;
if(i mod 2=0) then
for j:=n downto 1 do
Begin
A[i,j]:=B[k];
inc(k);
End;
inc(i);
End;
End;
Procedure Xuat;
Begin
Assign(fo,'SapXep.out');
rewrite(fo);
for i:=1 to m do
Begin
for j:=1 to n do write(fo,A[i,j]:3);
writeln(fo);
End;
close(fo);
End;
Begin
Nhap;
Chuyen1Chieu;
SapXep1Chieu;
Chuyen2Chieu;
Xuat;
End.
Bài 6: Sắp xếp 3
Cho một ma trận các số nguyên có kích thước nxm. Hãy sắp xếp ma trận tăn dần theo cấu trúc dưới
đây:

Buà i Họồ ng Dàộ n Pàgể 31


Dữ liệu vào: Lưu trong tệp SapXep.inp có cấu trúc như sau:
4
+ Dòng đầu tiên lưu hai số nguyên dương (m, n ≤ 10 ).
+ m dòng tiếp theo mỗi dòng lưu n số nguyên. Mỗi số cách nhau ít nhất một khoảng trắng.
Dữ liệu ra: Ghi vào tệp SapXep.out ma trận sau khi được sắp xếp.
Ví dụ:
SapXep.inp SapXep.out
3 7 1 2 3 4 5 6 7
3 1 2 10 11 12 20 16 17 18 19 20 21 8
4 6 5 14 15 13 21 15 14 13 12 11 10 9
7 9 8 18 17 19 16
Hướng dẫn:
Bước 1: Nhập ma trận từ file SapXep.inp.
Bước 2: Chuyển ma trận thành mảng 1 chiều.
Bước 3: Sắp xếp mảng 1 chiều.
Bước 4: Chuyển mảng 1 chiều thành 2 chiều theo đúng vị trí của từng phần tử.
Bước 5: Ghi ma trận đã được sắp xếp ra file SapXep.out.
Chú ý: Đối với ma trận vuông cấp (nxn) thì thuật toán chuyển từ mảng 1 chiều sang 2 chiều
đơn giản hơn.
Chương trình;
Program SapXep;
Var fi,fo: text;
n,m,i,j,Dem:integer;
k,t:longint;
A:array[1..10000,1..10000] of longint;
B:array[1..100000000] of longint;
Procedure HoanDoi(var a,b: longint);
Var Tam:longint;
Begin
Tam:=a;
a:=b;
b:=Tam;
End;
Procedure Nhap;
Begin
assign(fi,'SapXep.inp');
reset(fi);
readln(fi,m,n);
for i:=1 to m do
Begin
for j:=1 to n do read(fi,A[i,j]);
readln(fi);
End;
close(fi);
End;
Procedure Chuyen1Chieu;
Begin
k:=1;
for i:=1 to m do
for j:=1 to n do
Begin
B[k]:=A[i,j];
k:=k+1;
End;
End;
Procedure SapXep1Chieu;
Begin
for k:=1 to m*n-1 do
for t:=k+1 to m*n do
if B[k]>B[t] then HoanDoi(B[k],B[t]);
End;
Procedure Chuyen2Chieu;
var dd,dc,cd,cc:integer;
Begin
cd:=1; //cot dau;
cc:=n; //cot cuoi;
dd:=1; //dong dau;
dc:=m; //dong cuoi;
k:=1;
While(cd<=cc)and(dd<=dc) do
Begin
for i:=cd to cc do
Begin
A[dd,i]:=B[k];
inc(k);
End;
for i:=dd+1 to dc do
Begin
A[i,cc]:=B[k];
inc(k);
End;
if(dd<dc) then for i:=cc-1 downto cd do
Begin
A[dc,i]:=B[k];
inc(k);
End;
if(cd<cc) then for i:=dc-1 downto dd+1 do
Begin
A[i,cd]:=B[k];
inc(k);
End;
inc(dd); inc(cd); dec(cc); dec(dc);
End;
End;
Procedure Xuat;
Begin
Assign(fo,'SapXep.out');
rewrite(fo);
for i:=1 to m do
Begin
for j:=1 to n do write(fo,A[i,j]:3);
writeln(fo);
End;
close(fo);
End;
Begin
Nhap;
Chuyen1Chieu;
SapXep1Chieu;
Chuyen2Chieu;
Xuat;
End.
Xâu ký tự
Bài 1: Đối Xứng
Xâu đối xứng là xâu bằng chính xâu đảo của nó. Hãy kiểm tra xem một xâu có phải là xâu đối xứng
hay không?
Dữ liệu vào: Lưu trong tệp DoiXung.inp một xâu ký tự.
Dữ liệu ra: Ghi vào tệp DoiXung.out “Yes” nếu là xâu đối xứng, “No” nếu là xâu không đối xứng.
Ví dụ:
DoiXung.inp DoiXung.out
ABCBA Yes
DoiXung.inp DoiXung.out
ABCDE No
Hướng dẫn: Tạo xâu đảo ngược, so sánh xâu ban đầu với xâu đảo ngược.
Chương trình:
Program DoiXung;
Var fi,fo: text;
s,t:
string;
i:integer;
Begin
assign(fi,'DoiXung.inp');
reset(fi);
readln(fi,s);
close(fi);
t:='';
for i:=length(s) downto 1 do t:=t+s[i];
assign(fo,'DoiXung.out');
rewrite(fo);
if s=t then write(fo,'Yes') else write(fo,'No');
close(fo);
End.
Hoặc có thể dụng thuật toán nhanh hơn như sau:
Program DoiXung;
Var fi,fo:
text; s:
string;
kt:boolean;
i:integer;
Begin
assign(fi,'DoiXung.inp');
reset(fi);
readln(fi,s);
close(fi);
for i:=1 to (length(s)div 2) do
if (s[i]=s[length(s)-i+1]) then kt:=true
else
Begin
kt:=false;
break;
End;
assign(fo,'DoiXung.out');
rewrite(fo);
if kt=true then write(fo,'Yes') else write(fo,'No');
close(fo);
End.
Bài 2: Sửa lỗi
Lỗi thừa khoảng trắng giữa các từ trong một xâu văn bản rất thường gặp. Hãy viết chương trình sửa
lỗi một xâu văn bản bị lỗi khoảng trắng cho trước.
Dữ liệu vào: Lưu trong tệp SuaLoi.inp một xâu ký tự bị lỗi khoảng trắng.
Dữ liệu ra: Ghi vào tệp SuaLoi.out xâu đã được sửa hết lỗi.
Ví dụ:
SuaLoi.inp SuaLoi.out
Toi di hoc Toi di hoc

Chú ý: #32= ‘ ’;
Chương trình:
Program DoiXung;
Var fi,fo:
text; s:
string;
kt:boolean;
i:integer;
Begin
assign(fi,'SuaLoi.inp');
reset(fi);
readln(fi,s);
close(fi);
while(s[1]=#32) do delete(s,1,1); //Xoa ky tu trang o dau xau.
while(s[length(s)]=#32) do delete(s,length(s),1);//Xoa cuoi xau.
while(pos(#32#32,s)<>0) do delete(s,pos(#32#32,s),1);//Xoa giua.
assign(fo,'SuaLoi.out');
rewrite(fo);
write(fo,s);
close(fo);
End.
Bài 3: Liệt kê
Viết chương trình liệt kê tất cả các từ trong một xâu văn bản.
Dữ liệu vào: Lưu trong tệp LietKe.inp một xâu ký tự bị lỗi khoảng trắng.
Dữ liệu ra: Ghi vào tệp LietKe.out tất cả từ trong xâu văn bản đã cho, mỗi từ nằm trên một dòng.
Ví dụ
LietKe.inp LietKe.out
hom nay toi di hoc hom
nay
toi
di
hoc
Chương trình:
Program LietKe;
Var fi,fo: text;
s: string;
Begin
assign(fi,'LietKe.inp');
reset(fi);
readln(fi,s);
close(fi);
assign(fo,'LietKe.out');
rewrite(fo);
s:=s+#32;
while(pos(#32,s)<>0) do
Begin
writeln(fo,copy(s,1,pos(#32,s)-1));
delete(s,1,pos(#32,s));
End;
close(fo);
End.
Lưu ý: Xâu văn bản trong input của trương trình trên là không có lỗi khoảng trắng, không có dấu
câu. Nếu input có lỗi khoảng trắng thì gọi thủ tục sửa lỗi (bài 2) trước khi liệt kê các từ. Nếu xâu
văn bản có các dấu câu thì chương trình sửa lại như sau:
LietKe.inp LietKe.out
hom nay, hom qua. hom
nay
hom
qua
Chương trình:
Program LietKe;
Var fi,fo:
text; s,t:
string;
Begin
assign(fi,'LietKe.inp');
reset(fi);
readln(fi,s);
close(fi);
assign(fo,'LietKe.out');
rewrite(fo);
s:=s+#32;
while(pos(#32,s)<>0) do
Begin
t:=copy(s,1,pos(#32,s)-1);
if(t[length(t)]=',') or (t[length(t)]='.')
//Co the co nhieu dau cau khac nua.
then delete(t,length(t),1);
writeln(fo,t);
delete(s,1,pos(#32,s));
End;
close(fo);
End.
Bài 4: Liệt kê 2
Cho một xâu văn bản, hãy liệt kê tất cả các chữ cái và số lượng của nó (không phân biệt chữ hoa và
chữ thường.
Dữ liệu vào: Lưu trong tệp LietKe.inp một xâu ký tự bị lỗi khoảng trắng.
Dữ liệu ra: Ghi vào tệp LietKe.out tất cả các chữ cái và số lượng của nó theo thứ tự từ điển. Có
cấu trúc như ví dụ sau:
Ví dụ:
SuaLoi.inp SuaLoi.out
ABC DEF ABF A 2
B 2
C 1
D 1
E 1
F 2
Chương trình:
Program LietKe;
Var fi,fo:
text; s:
string;
Dem:array['A'..'Z'] of byte;
i:integer;
ch:char;
Begin
assign(fi,'LietKe.inp');
reset(fi);
readln(fi,s);
close(fi);
for i:=1 to length(s) do
if (upcase(s[i]) in ['A'..'Z'])
then inc(Dem[upcase(s[i])]);
assign(fo,'LietKe.out');
rewrite(fo);
for ch:='A' to 'Z' do
if Dem[ch]>0 then writeln(fo,ch,' ',Dem[ch]);
close(fo);
End.
Bài 5: Đếm từ
Cho một xâu văn bản và một từ (mỗi từ ngăn cách với từ khác bằng một khoảng trắng). Hãy cho
biết từ đó xuất hiện bao nhiêu lần trong xâu văn bản đã cho.
Dữ liệu vào: Lưu trong tệp DemTu.inp có cấu trúc như sau:
+ Dòng 1: Lưu từ cần đếm.
+ Dòng 2: Lưu xâu văn bản.
Dữ liệu ra: Ghi vào tệp Demtu.out số lượng từ đã cho xuất hiện trong xâu.
Ví dụ:
DemTu.inp DemTu.out
AB 3
AB ABCD AB BCAB AB
Chương trình:
Program DemTu;
Var fi,fo: text;
s,tu: string;
Dem:integer;
Begin
assign(fi,'DemTu.inp');
reset(fi);
readln(fi,tu);
read(fi,s);
close(fi);
Dem:=0;
if(pos(tu+#32,s)=1) then inc(Dem); // KT tu dau;
if(copy(s,length(s)-length(tu),length(tu)+1)=#32+tu)
then inc(Dem); //Kiem tra ky tu o cuoi;
tu:=#32+tu+#32;
while(pos(tu,s)>0) do //Kiem tra cac tu o giua;
Begin
inc(Dem);
delete(s,pos(tu,s),length(tu)-1);
End;
assign(fo,'DemTu.out');
rewrite(fo);
write(fo,Dem);
close(fo);
End.
Bài 6: Palindrom
Một số nguyên gọi là palindrom nếu nó đọc từ trái sang cũng bằng đọc từ phải sang. Cho một dãy
gồm nhiều phần tử nguyên dương. Hãy cho biết có bao nhiêu số là palindrom và hiển thị các số đó
theo thứ tự xuất hiện trong dãy.
8 8
Dữ liệu vào: Lưu trong tệp Palindrom.inp một dãy số (≤10 phần tử) nguyên dương. Mỗi số (≤10 )
cách nhau ít nhất một khoảng trắng.
Dữ liệu ra: Ghi vào tệp Palindrom.out có cấu trúc như sau: Mỗi dòng ghi một số palindrom theo
thứ tự xuất hiện trong dãy.
Ví dụ:

Palindrom.inp Palindrom.out
121 1 1234 22 235 121
1
22
Chương trình:
Program Palindrom;
Var fi,fo:
text; s:
string;
i:integer;
a:longint;
Function DoiXung(k:string): boolean;
var t:string;
Begin
t:='';
for i:=length(k) downto 1 do t:=t+k[i];
if t=k then DoiXung:=True else DoiXung:=False;
End;
Begin
assign(fi,'palindrom.inp');
reset(fi);
assign(fo,'palindrom.out');
rewrite(fo);
while(EOF(fi)=False) do
Begin
read(fi,a);
str(a,s);
if(DoiXung(s)=true) then writeln(fo,a);
End;
close(fi);
close(fo);
End.

Buà i Họồ ng Dàộ n Pàgể 40


Một số bài toán
Bài 1: Fibonacci.
Dãy Fibonacci là dãy vô hạn các số tự nhiên bắt đầu bằng hai phần tử 0 và 1, các phần tử sau đó
được thiết lập theo quy tắc mỗi phần tử luôn bằng tổng hai phần tử trước nó. Công thức truy hồi
của dãy Fibonacci là:

F(n)={
( ) ( )
Yêu cầu: Tìm số Fibonacci thứ n.
8
Dữ liệu vào: Lưu trong tệp Fibo.inp một số nguyên dương n (n ≤ 10 ).
Dữ liệu ra: Ghi vào tệp Fibo.out số Fibonacci thứ n.
Ví dụ:
Fibo.inp Fibo.out
8 21
Chương trình:
Program Fibonacci;
Var fi,fo: text;
i,n,x,y,z:integer;
Begin
assign(fi,'Fibo.inp');
reset(fi);
readln(fi,n);
close(fi);
x:=0; y:=1;
for i:=2 to n do
begin
z:=x+y;
x:=y;
y:=z;
End;
assign(fo,'Fibo.out');
rewrite(fo);
write(fo,z);
close(fo);
End.
Bài 2: Số hoàn hảo
Số hoàn hảo được định nghĩa như sau:
+ 1 không phải là số hoàn hảo.
+ Có tổng các ước nhỏ hơn nó bằng chính nó.
Yêu cầu: Hãy liệt kê tất cả các số hoàn hảo nhỏ hơn một số nguyên cho trước.
4
Dữ liệu vào: Lưu trong tệp SoHH.inp một số nguyên dương n (n ≤ 10 ).
Dữ liệu ra: Ghi vào tệp SoHH.out tất cả cá số hoàn hảo nhỏ hơn n.
Ví dụ:
SoHH.inp SoHH.out

Buà i Họồ ng Dàộ n Pàgể 41


10000 6
28
496
8128
Chương trình:
Program SoHoanHao;
Var fi,fo:
text;
i,n:integer;
Function SoHH(x:integer):boolean;
Var sum,j:integer;
Begin
sum:=0;
for j:=1 to x-1 do
if(x mod j=0) then inc(sum,j);
if(sum=x) then SoHH:=true else SoHH:=false;
End;
Begin
assign(fi,'SoHH.inp');
reset(fi);
readln(fi,n);
close(fi);
assign(fo,'SoHH.out');
rewrite(fo);
for i:=2 to n-1 do if(SoHH(i)=true) then writeln(fo,i);
close(fo);
End.
Bài 3: Thừa số nguyên tố
Hãy phân tích một số ra thành thừa số nguyên tố.
6
Dữ liệu vào: Lưu trong tệp TSNT.inp một số nguyên dương n (n ≤ 10 ).
Dữ liệu ra: Ghi vào tệp TSNT.out tích các thừa số nguyên tố.
Ví dụ:
TSNT.inp TSNT.out
18 2 * 3 *3
Chương trình:
Program ThuaSoNguyenTo;
Var fi,fo:
text;
i,n:integer;
Begin
assign(fi,'TSNT.inp');
reset(fi);
readln(fi,n);
close(fi);
assign(fo,'TSNT.out');
rewrite(fo);
i:=2;
repeat
while(n mod i<>0) do i:=i+1;
write(fo,i);
n:=n div i;
if n>1 then write(fo,'*');
until n=1;
close(fo);
End.
Bài 4: Xóa phần tử trùng nhau
Cho dãy số gồm n số nguyên. Nếu số nguyên nào xuất hiện nhiều lần thì chỉ giữ lại 1 số xuất hiện
đầu tiên trong dãy.
Dữ liệu vào: Lưu trong tệp Xoa.inp có cấu trúc như sau:
7
+ Dòng thứ nhất lưu số nguyên n (n ≤ 10 ) cho biết số phần tử trong dãy.
+ Dòng thứ hai lưu n số nguyên mỗi số cách nhau ít nhất một khoảng trắng.
Dữ liệu ra: Ghi vào tệp Xoa.out tổng của các số nguyên tố.
Ví dụ:
Xoa.inp Xoa.out
5 2 3 4
2 3 4 3 2
Hướng dẫn: Duyệt mảng bằng 2 biết, nếu phát hiện phần tử nào bằng nhau thì xóa bớt một phần từ
ra khỏi mảng.
Chương trình:
Program XoaPhanTu;
Var fi,fo: text;
n,i,j,k:longint;
A:array[1..10000000] of longint;
Begin
assign(fi,'Xoa.inp');
reset(fi);
readln(fi,n);
for i:=1 to n do read(fi,A[i]);
close(fi);
i:=2;
while(i<=n) do
Begin
j:=1;
while(A[j]<>A[i]) do inc(j);
if(j<i) then
begin
for k:=i to n-1 do A[k]:=A[k+1];
dec(n);
End
else inc(i);
End;
assign(fo,'Xoa.out');
rewrite(fo);
for i:=1 to n do write(fo,A[i],' ');
close(fo);
End.
3
Lưu ý: Thuật toán trên có độ phức tạp O(n ). Ngoài ra còn có thuật toán độ phức tạp O(n) gợi ý như
dưới đây:
+ Sử dụng biến kiểu cấu trúc có 2 thành phần, một thành phần lưu giá trị, một thành phần
lưu vị trí dầu tiên.
+ Sử dụng mảng để lưu số lần xuất hiện của mỗi phần tử.
+ Sắp xếp lại theo vị trí xuất hiện (sử dụng thuật toán sắp xếp có độ phức tạp O(n)).
+ Xuất ra mảng được sắp xếp theo vị trí xuất hiện.
Bài 5: Tổng m số
Cho số tự nhiên n và một số nguyên dương m. Hãy tính tổng m số tận cùng của n.
Dữ liệu vào: Lưu trong tệp TongM.inp hai số n và m cách nhau ít nhất một khoảng trắng.
Dữ liệu ra: Ghi vào tệp TongM.out tổng m số tận cùng của n.
Ví dụ:
TongM.inp TongM.out
123456 3 15
Chương trình:
Program TongM;
Var fi,fo: text;
n,i,m,tong:longint;
Begin
assign(fi,'TongM.inp');
reset(fi);
read(fi,n,m);
close(fi);
tong:=0;
for i:=1 to m do
Begin
tong:=tong+(n mod 10);
n:=n div 10;
End;
assign(fo,'TongM.out');
rewrite(fo);
write(fo,tong);
close(fo);
End.
Bài 6: Bội chung nhỏ nhất.
Cho dãy số gồm n số nguyên dương. Hãy tìm bội chung nhỏ nhất của dãy số đó.
Dữ liệu vào: Lưu trong tệp BCNN.inp có cấu trúc như sau:
7
+ Dòng thứ nhất lưu số nguyên n (n ≤ 10 ) cho biết số phần tử trong dãy.
+ Dòng thứ hai lưu n số nguyên mỗi số cách nhau ít nhất một khoảng trắng.
Dữ liệu ra: Ghi vào tệp BCNN.out tổng của các số nguyên tố.
Ví dụ:
BCNN.inp BCNN.out
5 2 3 4
2 3 4 3 2
Hướng dẫn: Để tìm BCNN của {2,3,4,3,2) ta tìm BCNN(BCNN(BCNN(BCNN(2,3),4),3),2).
Chương trình:
Program BoiChungNhoNhat;
Var fi,fo: text;
n,i,BCNN,UCLN:longint;
A:array[1..10000000] of longint;
Function F_UCLN(a,b:integer): integer;
Begin
While(a<>b) do
if a>b then a:=a-b else b:=b-a;
UCLN:=a;
End;
Begin
assign(fi,'BCNN.inp');
reset(fi);
readln(fi,n);
for i:=1 to n do read(fi,A[i]);
close(fi);
UCLN:=F_UCLN(A[1],A[2]);
BCNN:=(A[1]*A[2])div UCLN;;
for i:=3 to n do
Begin
UCLN:=F_UCLN(BCNN,A[i]);
BCNN:=((BCNN*A[i])div UCLN);
End;
assign(fo,'BCNN.out');
rewrite(fo);
write(fo,BCNN);
close(fo);
End.
Bài 7: Đảo ngược.
Cho một xâu văn bản. Hãy đưa ra xâu đảo theo từ.
Dữ liệu vào: Lưu trong tệp DaoNguoc.inp một xâu văn bản:
Dữ liệu ra: Ghi vào tệp DaoNguoc.out xâu đảo theo từ.
Ví dụ:
DaoTu.inp DaoTu.out
ban di hoc hoc di ban
Chương trình:
Program DaoNguoc;
Var fi,fo: text;
s:string;
x,j,i:integer;
Begin
assign(fi,'DaoNguoc.inp');
reset(fi);
readln(fi,s);
close(fi);
assign(fo,'DaoNguoc.out');
rewrite(fo);
x:=length(s);
for i:=x-1 downto 1 do
Begin
if(s[i]=' ') then
Begin
for j:=i+1 to x do write(fo,s[j]);
write(fo,' ');
x:=i-1;
End;
if(i=1) then for j:=1 to x do write(fo,S[j]);
End;
close(fo);
End.
Bài 8: Đếm ký tự.
Cho một xâu văn bản. Hãy cho biết có bao nhiêu ký tự chữ và bao nhiêu ký tự số.
Dữ liệu vào: Lưu trong tệp DemKyTu.inp một xâu văn bản:
Dữ liệu ra: Ghi vào tệp DemKyTu.out có cấu trúc như sau:
+ Dòng 1: Ghi số ký tự chữ.
+ Dòng 2: Ghi số ký tự số.
Ví dụ:
DemKyTu.inp DemKyTu.out
123ABCcde123 6
6
Chương trình:
Program DemKyTu;
Var fi,fo: text;
s:string;
Dem1,Dem2,i:integer;
Begin
assign(fi,'DemKyTu.inp');
reset(fi);
readln(fi,s);
close(fi);
Dem1:=0; Dem2:=0;
for i:=1 to length(S) do
Begin
if(s[i] in ['0'..'9']) then inc(Dem2);
if(s[i] in ['A'..'Z']+['a'..'z']) then inc(Dem1);
End;
assign(fo,'DemKyTu.out');
rewrite(fo);
writeln(fo,Dem1);
write(fo,Dem2);
close(fo);
End.
Bài 9: Connect
Cho n số nguyên dương a1, a2,…, ai,…, an. Từ các số nguyên này người ta tạo ra một số nguyên mới
bằng cách kết nối tất cả các số đã cho viết liên tiếp nhau. Ví dụ, với n=4 và các số 12, 34, 567, 890
ta có thể tạo ra các số mới như sau: 1234567890, 3456789012, 8905673412,… Dễ thấy rằng có 4!
=24 cách tạo mới như vậy.
Trong trường hợp này, số lớn nhất có thể tạo thành là 8905673412.
9
Yêu cầu: Cho n (1<n≤100) và các số a1, a2,…, ai,…, an (0<ai≤10 ). Hãy xác định số lớn nhất có thể
kết nối được theo nguyên tắc trên.
Dữ liệu vào: Lưu trong tệp văn bản Connect.inp gồm n+1 dòng.
+ Dòng đầu tiên ghi số nguyên n.
+ Trong các dòng còn lại, dòng thứ i+1 ghi số ai.
Dữ liệu ra: Ghi vào tệp Connect.out số lớn nhất được kết nối thành từ các số ban đầu.
Ví dụ:
Connect.inp Connect.out
4 8905673412
12
34
567
890
Hướng dẫn: Gọi a là dãy gồm n chuỗi số đã cho. Sắp xếp theo tiêu chuẩn nếu ai+aj<aj+ai thì ta
hoán vị ai và aj. Xuất dãy a ta được kết quả.
Chương trình:
Program Connect;
Var fi,fo: text;
n,i,j,x:longint;
tam:
string[10];
A:array[1..100] of string[10];
Begin
assign(fi,'Connect.inp');
reset(fi);
readln(fi,n);
for i:=1 to n
do
Begin
readln(fi,x);
str(x,A[i]);
End;
for i:=1 to n-1 do
for j:=i+1 to n do
if A[i]<A[j] then
Begin
tam:=A[i];
A[i]:=A[j];
A[j]:=Tam;
End;
close(fi);
assign(fo,'Connect.out');
rewrite(fo);
for i:=1 to n do write(fo,A[i]);
close(fo);
End.
Bài 10: Dấu ngoặc
Cho một xâu S không vượt quá 1000 ký tự chỉ bao các dấu mở ngoặc “(” và các dấu đóng ngoặc
“)”, theo quy tắc ưu tiên tính toán trong biểu thức. Tương ứng dấu mở ngoặc đứng trước là một dấu
đóng ngoặc đứng sau được gọi là một cặp dấu ngoặc.
Yêu cầu: Hãy viết chương trình đưa ra vị trí của các cặp dấu ngoặc trong xâu S theo thứ tự ưu tiên
tính toán trong biểu thức (nếu các cặp dấu ngoặc bao nhau thì vị trí cặp dấu ngoặc được bao bên
trong trước, vị trí cặp dấu ngoặc bao bên ngoài sau.
Dữ liệu vào: Lưu trong tệp DauNgoac.inp chỉ một dòng chứa xâu S.
Dữ liệu ra: Ghi vào tệp DauNgoac.out, mỗi dòng là một cặp số chỉ vị trí của dấu “(” và dấu “)”
theo đúng thứ tự ưu tiên tính toán.
Ví dụ:
DauNgoac.inp DauNgoac.out
()(()) 1 2
4 5
3 6
Hướng dẫn: Dùng biến k để đếm xem có bao nhiêu dấu mở ngoặc chưa gặp dấu đóng ngoặc. Dùng
mảng A để lưu vị trí các dấu mở ngoặc chưa đóng. Nếu gặp dấu đóng ngoặc thì hiển thị vị trí dấu
mở ngoặc chưa đóng cuối cùng trước nó và vị trí của nó, đồng thời giảm biến k xuống một đơn vị
để kiểm soát số ngoặc còn lại chưa được đóng.
Chương trình:
Program DauNgoac;
Var fi,fo: text;
i,k:integer;
s:ansistring; //Kieu xau dai;
A:array[1..1000] of integer;
Begin
assign(fi,'DauNgoac.inp');
reset(fi);
readln(fi,S);
close(fi);
assign(fo,'DauNgoac.out');
rewrite(fo);
k:=0;
for i:=1 to length(s) do
if(s[i]='(') then
Begin
inc(k);
A[k]:=i;
End
else if(S[i]=')') then
Begin
writeln(fo,A[k],' ',i);
dec(k);
End;
close(fo);
End.
Bài 11: Chuỗi con đối xứng dài nhất
Cho một chuỗi S dài không quá 255 ký tự. Hãy cho biết độ dài chuỗi con đối xứng dài nhất trong
chuỗi S.
Dữ liệu vào: Lưu trong tệp CCDX.inp chỉ một dòng chứa xâu S.
Dữ liệu ra: Ghi vào tệp CCDX.out độ dài chuỗi con đối xứng dài nhất
Ví dụ:
CCDX.inp CCDX.out
ABCDDCBDE 6
Giải thích: Chuỗi con đối xứng dài nhất là BCDDCB
Chương trình:
Program ChuoiConDoiXung;
Var fi,fo: text;
i,j,k,max:integer;
s:string;
KiemTra:boolean;
Begin
assign(fi,'CCDX.inp');
reset(fi);
readln(fi,S);
close(fi);
max:=1;
for i:=1 to length(s) do
Begin
for j:=length(s) downto i+1 do
if(S[i]=S[j]) then
Begin
KiemTra:=true;
for k:=0 to ((j-i) div 2) do
if(S[i+k]<>S[j-K]) then
Begin
KiemTra:=false;
break;
End;
if(KiemTra=true) then
if(j-i+1>max) then max:=j-i+1;
End;
End;
assign(fo,'CCDX.out');
rewrite(fo);
write(fo,max);
close(fo);
End.
Bài 12: Loại bỏ
Cho số tự nhiên n. Hãy tìm số m bằng cách loại bỏ đi trong n tất cả các chữ số 0 và 5. Các chữ số
còn lại giữ nguyên thứ tự. Ví dụ: n = 50915509 thì m = 919.
Dữ liệu vào: Lưu trong tệp LoaiBo.inp một số tự nhiên n.
Dữ liệu ra: Ghi vào tệp LoaiBo.out số m.
Ví dụ:
LoaiBo.inp LoaiBo.out
50915509 919
Hướng dẫn:
Cách 1: Cho lần lượt từng số hạng của n vào mảng A. Sau đó hiển thị các phần tử của mảng A
không phải là 5 hoặc 0.
Cách 2: Chuyển số n thành xâu. Hiển thị xâu loại bỏ ký tự „5‟ và ký tự „0‟.
Chương trình:
Program LoaiBo;
Var n,i,dem:longint;
fi,fo:text;
A:array[1..100]of
integer;
Begin
assign(fi,'LoaiBo.inp');
reset(fi);
read(fi,n);
close(fi);
i:=0; dem:=0;
while(n>0) do
Begin
inc(i);inc(dem);
A[i]:= n mod 10;
n:= n div 10;
End;
assign(fo,'LoaiBo.out');
rewrite(fo);
for i:=dem downto 1 do
if(A[i]<>0)and(A[i]<>5) then write(fo,A[i]);
close(fo);
End.
Bài 13: Dãy con.
Cho một dãy số gồm n số nguyên dương, hãy cho biết xem có bao nhiêu dãy con liên tiếp có tổng
bằng một số nguyên k cho trước.
Dữ liệu vào: Lưu trong tệp DayCon.inp có cấu trúc như sau:
7
Dòng 1:Lưu hai số nguyên n và k (n≤10 ).
Dòng 2: Lưu n số nguyên dương, mỗi số cách nhau một khoảng trắng.
Dữ liệu ra: Ghi vào tệp DayCon.out số dãy con có tổng bằng k.
Ví dụ:
DayCon.inp DayCon.out
7 5 3
3 2 1 5 4 3 2
Giải thích: Có 3 dãy con đó là: 3 2 1; 5; 3 2.
Ghi chú: Có rất nhiều thuật toán giải bài toán này. Đơn giản nhất là thuật toán tìm tất cả các dãy
3
con, với mỗi dãy con ta tiến hành tính tổng, thì có độ phức tạp O(n ). Sau đây là thuật toán với độ
phức tạp O(n).
Chương trình:
Program DayCon;
Var n,i,dem,k,j,tong:longint;
fi,fo:text;
A:array[1..10000000]of
integer;
Begin
assign(fi,'DayCon.inp');
reset(fi);
readln(fi,n,k);
for i:=1 to n do read(fi,A[i]);
close(fi);
j:=1; tong:=0; dem:=0;
for i:=1 to n do
Begin
tong:=tong+A[i];
if(tong>k) then
While(tong>k)and(j<i) do

Buà i Họồ ng Dàộ n Pàgể 50


Begin

Buà i Họồ ng Dàộ n Pàgể 50


tong:=tong-A[j];
inc(j);
End;
if(tong=k) then inc(dem);
End;
assign(fo,'DayCon.out');
rewrite(fo);
write(fo,dem);
close(fo);
End.

---------------continue---------------

Buà i Họồ ng Dàộ n Pàgể 51


MỘT SỐ THỦ TỤC VÀ HAM THÔNG DỤNG
CÁC THỦ TỤC THÔNG DỤNG
Str(x,S) đổi giá trị kiểu số X sang dạng chuỗi S.
Val(S,x,code) đổi chuỗi S thành sô x. Nếu đổi chuỗi thành công biến Code nhận giá trị 0. Nếu
không đổi được code là số nguyên cho biêt vị trí gây lỗi.
Inc(x,r) tăng giá trị của x nên r đơn vị. Tương đương với x:=x+r;
Dec(x,r) giảm giá trị của x xuống r đơn vị. Tương đương với x:=x-r. (thủ tục Inc(x), Dec(x) xem
như tăng, giảm x một đơn vị)
Insert(S,T,vt) chèn chuoi S vào chuoi T vtrí vt.
Delete(S,P,L) xoá L ký tự từ vị trí P ra khỏi.
Break kết thúc vòng lặp
CÁC HÀM THÔNG DỤNG
Ord(x) lấy thứ tự của ký tự x trong bản mã ASCII.
Chr(x) lấy ký tự thứ x trong bảng mã ASCII.
Pred(x) cho phần tử đứng trước x.
Succ(x) cho ra phần tử đứng sau x.
Round(x) làm tròn x.
Trunc(x) lấy phần nguyên.
Int(x) lấy phần nguyên.
Frac(x) lấy phần lẻ.
Abs(x) lấy giá trị tuyệt đối.
Copy(S,P,L) trích chuỗi S một chuỗi con dài L ký tự bắt đầu từ vtrí P.
Odd(i:Integer) cho True khi i là sô lẻ và False khi i là sô chẵn.
Pos(X,S) cho vị trí bắt đầu của chuỗi con X trong S. Nêu X không thuộc S thì hàm POS cho giá trị
0.
CÁC LỖI EXIT CODE DO RUN –TIME CỦA FREEPASCAL
Applications generated by Free Pascal might generate Run-time error when certain abnormal
conditions are detected in the application. This appendix lists the possible run-time errors and gives
information on why they might be produced.
Chương trình được viết bởi Free Pascal có thể sinh ra các lỗi chạy thực (Run-Time Error) khi nhưng
điều kiện khác thường được dò thấy trong chương trình. Danh sách sau liệt kê các lỗi chạy thực
(Run-time Error) và các thông tin về lỗi đó.

1 Invalid function number An invalid operating system call was attempted.


Thực hiện 1 hàm số vô nghĩa hoặc thực hiện 1 lời gọi hệ điều hành vô nghĩa.

2 File not found Reported when trying to erase, rename or open a non-existent file.
Không tìm thấy file. Lỗi được báo khi có những lệnh Erase, Rename hoặc là Mở một file không tồn
tại.

3 Path not found Reported by the directory handling routines when a path does not exist or is
invalid.
Không tìm thấy file. Lỗi được báo khi đường dẫn đến file không tìm thấy được hoặc vô nghĩa.
Also reported when trying to access a non-existent file.
Cũng có thể được báo khi có lệnh truy cập 1 file không tồn tại.

4 Too many open files The maximum number of currently opened files by your process has been
reached. Certain operating systems limit the number of files which can be opened concurrently, and
this error can occur when this limit has been reached.
Quá nhiều file đã mở. Chương trình đã đạt tới giới hạn file được mở. Tuỳ hệ điều hành mà giới hạn
file được mở khác nhau, và lỗi này được báo khi số file mở đạt tới giới hạn đó.

5 File access denied Permission accessing the file is denied. This error might be caused by several
reasons:
Sự truy cập file bị từ chối. Lỗi này xảy ra khi 1 trong những lỗi sau xãy ra:
• Trying to open for writing a file which is read only, or which is actually a directory.
Có lệnh thực hiện ghi lên file có thuộc tính chỉ đọc (Read-only) hoặc đó chỉ là đường dẫn.
• File is currently locked or used by another process.
File hiện thời bị khoá hoặc bị chiến dụng bởi 1 ứng dụng khác.
• Trying to create a new file, or directory while a file or directory of the same name already
exists. Có lệnh tạo 1 file mới, hoặc 1 đường dẫn mới trùng với 1 file hoặc 1 đường dẫn đã tồn tại.
• Trying to read from a file which was opened in write only mode.
Có lệnh thực hiện đọc 1 file chỉ có thuộc tính chỉ ghi (Write-only)
• Trying to write from a file which was opened in read only mode.
Có lệnh thực hiện ghi vào 1 file đã mở với chế độ chỉ đọc (Read-only)
• Trying to remove a directory or file while it is not possible.
Có lệnh thực hiện xoá (gỡ) 1 đường dẫn hoặc 1 file không có thực
• No permission to access the file or directory.
Quyền truy cập vào file bị khoá.

6 Invalid file handle If this happens, the file variable you are using is trashed; it indicates that your
memory is corrupted.
File thực hiện vô nghĩa. Nếu lỗi này xảy ra, biến file đang được sử dụung đã bị lỗi; có nghĩa là bộ
nhớ đã bị lỗi.

12 Invalid file access code Reported when a reset or rewrite is called with an invalid FileMode
value.
Mã truy cập file vô nghĩa. Lỗi được báo khi lệnh Reset hoặc Rewrite được gọi với 1 giá trị chế độ
File vô nghĩa.

15 Invalid drive number The number given to the Getdir or ChDir function specifies a nonexistent
disk.
Ổ đĩa vô nghĩa. Số được trả bởi hàm Getdir hoặc ChDir chỉ 1 ổ đĩa không tồn tại

16 Cannot remove current directory Reported when trying to remove the currently active directory.
Không thể xoá đường dẫn hiện thời. Lỗi được báo khi có lệnh xoá 1 đường dẫn đang được sử dụng.

17 Cannot rename across drives You cannot rename a file such that it would end up on another disk
or partition.
Không thể đổi tên file mà trỏ đến 1 ổ đĩa khác hoặc 1 phân vùng khác của ổ đĩa.

100 Disk read error An error occurred when reading from disk. Typically when you try to read past
the end of a file.
Lỗi đọc đĩa. Lỗi xãy ra trong khi đọc file từ đĩa. Điển hình khi có lệnh tiếp tục đọc phần tiếp theo
của cuối file.

101 Disk write error Reported when the disk is full, and you‟re trying to write to
it. Lỗi ghi đĩa. Lỗi được báo khi đĩa đã đầy và có lệnh ghi vào đĩa đó.

102 File not assigned This is reported by Reset, Rewrite, Append, Rename and Erase, if you call
them with an unassigned file as a parameter.
File chưa được khai báo. Lỗi được báo khi lệnh Reset, Rewrite, Append, Rename và Erase được
gọi với 1 biến chưa được khai báo.

103 File not open Reported by the following functions : Close, Read, Write, Seek, EOf, FilePos,
FileSize, Flush, BlockRead, and BlockWrite if the file is not open.
File chưa được mở. Lỗi được báo khi các lệnh sau được gọi: Close, Read, Write, Seek, Eof,
FilePos, FileSize, Flush, BlockRead, và BlockWrite nếu chưa mở file.

104 File not open for input Reported by Read, BlockRead, Eof, Eoln, SeekEof or SeekEoln if the
file is not opened with Reset.
File chưa mở để đọc. Lỗi được báo khi các lệnh sau được gọi: Read, BlockRead, Eof, Eoln,
SeekEof hoặc SeekEoln nếu file chưa được mở bằng lệnh Reset.

105 File not open for output Reported by write if a text file isn‟t opened with Rewrite.
File chưa được mở để ghi. Lỗi được báo khi 1 biến kiểu Text chưa được mở bằng lệnh Rewrite.

106 Invalid numeric format Reported when a non-numeric value is read from a text file, when a
numeric value was expected.
Sai kiểu số. Lỗi được báo khi 1 giá trị ký tự được đọc từ file kiểu Text, khi mà biến đọc vào là 1
biến số.

150 Disk is write-protected (Critical error)


Đĩa ở chế độ Ngăn cản ghi (Write-Protected)

151 Bad drive request struct length (Critical error)

152 Drive not ready (Critical


error) Ổ đĩa chưa chuẩn bị.

154 CRC error in data (Critical error)


Lỗi kiểm tra độ dư vòng (Cyclic redundancy check – CRC) trong dữ liệu.

156 Disk seek error (Critical


error) Tìm kiếm ổ đĩa không
được.

157 Unknown media type (Critical error)


Định dạng phương tiện truyền thông không chấp nhận.
158 Sector Not Found (Critical
error) Cung từ trên ổ đĩa không tìm
thấy.

159 Printer out of paper (Critical


error) Máy in không có giấy.

160 Device write fault (Critical error)


Thiết bị ghi lỗi.

161 Device read fault (Critical error)


Thiết bị đọc lỗi.

162 Hardware failure (Critical


error) Lỗi ổ cứng.
(Lỗi 150-162 là lỗi phần cứng)

200 Division by zero The application attempted to divide a number by zero.


Lỗi chia cho 0. Chương trình đang cố chia 1 số cho 0 (Kinh nghiệm là lỗi này xảy ra khi cố gọi
Unit Crt khi thiếu thư viện này)

201 Range check error If you compiled your program with range checking on, then you can get this
error in the following cases:
Lỗi kiểm tra vùng xãy ra. Nếu trình biên dịch có chế độ Kiểm tra vùng (Range-Checking) được
mở, thì có thể xãy ra các lỗi sau:
1. An array was accessed with an index outside its declared
range. Có lệnh truy cập vào 1 vùng nằm ngoài khai báo 1 Array.
2. Trying to assign a value to a variable outside its range (for instance an enumerated
type). Có lệnh gán giá trị vượt quá giới hạn giá trị của biến.

202 Stack overflow error The stack has grown beyond its maximum size (in which case the size of
local variables should be reduced to avoid this error), or the stack has become corrupt. This error is
only reported when stack checking is enabled.
Tràn chồng đợi (Stack). Chồng đợi đã vượt qua giới hạn (có thể giảm dung lượng hoặc không xài
biến cục bộ để giảm thiểu lỗi này) hoặc chồng đợi có lỗi. Lỗi này chỉ được báo khi trình biên dịch
có chế độ Kiểm tra Chồng đợi (Stack Checking) được mở.

203 Heap overflow error The heap has grown beyond its boundaries. This is caused when trying to
allocate memory exlicitly with New, GetMem or ReallocMem, or when a class or object instance is
created and no memory is left. Please note that, by default, Free Pascal provides a growing heap, i.e.
the heap will try to allocate more memory if needed. However, if the heap has reached the
maximum size allowed by the operating system or hardware, then you will get this error.
Tràn Heap. Heap đã đạt tới giới hạn. Lỗi xãy ra khi có lệnh chỉ định Memory Exlicitly (?) với lệnh
New, GetMen hoặc ReallocMem, hoặc khi 1 lớp đối tượng được tạo ra và tràn bộ nhớ. Lưu ý:
FreePascal cung cấp 1 Heap tự động: Ví dụ nếu Heap đã đạt giá trị cực đại, FreePascal sẽ chỉ định
thêm vùng nhớ nếu cần. Nhưng nếu Heap đã đạt giá trị cực đại cho phép bởi hệ điều hành hoặc
phần cứng thì lỗi sẽ xảy ra.

204 Invalid pointer operation This you will get if you call Dispose or Freemem with an invalid
pointer (notably, Nil)
Lỗi phép toán Con trỏ. Lỗi xảy ra khi có lệnh Dispose hoặc FreeMem một con trỏ Nil hoặc không
xác định.

205 Floating point overflow You are trying to use or produce too large real numbers.
Lỗi tràn số. Lỗi xãy ra khi có lệnh sử dụng hoặc sinh ra 1 số thực quá lớn.

206 Floating point underflow You are trying to use or produce too small real
numbers. Lỗi tràn số. Lỗi xãy ra khi có lệnh sử dụng hoặc sinh ra 1 số thực quá nhỏ.

207 Invalid floating point operation Can occur if you try to calculate the square root or logarithm of
a negative number.
Lỗi số không xác định. Lỗi xảy ra khi có phép tính toán một căn thức hoặc hàm Log của 1 số âm.

210 Object not initialized When compiled with range checking on, a program will report this error
if you call a virtual method without having called istr constructor.
Đối tượng không có giá trị ban đầu. Khi biên dịch với trình có Kiểm tra Vùng (Range-Checking)
được mở, chương trình sẽ báo lỗi này nếu có lệnh gọi 1 phương pháp ảo (?) không có đối tượng xây
dựng (?)

211 Call to abstract method Your program tried to execute an abstract virtual method. Abstract
methods should be overridden, and the overriding method should be called.
Trừu tượng hoá phương pháp (?) Chương trình đang có thi hành 1 phương pháp ảo trừu tượng (?).
Phương pháp trừu tượng nên được ghi đè, và phương pháp đã được ghi đè nên được gọi thay.

212 Stream registration error This occurs when an invalid type is registered in the objects unit.
Lỗi đăng ký luồng. Lỗi xảy ra khi 1 kiểu biến không hợp lệ đăng ký trên thư viện Object.

213 Collection index out of range You are trying to access a collection item with an invalid
index(objects unit).
Thu thập danh mục ngoài vùng. Lỗi xãy ra khi có lệnh truy cập những thông tin thu thập được với
danh mục không xác định (lỗi trong thư viện Object)

214 Collection overflow error The collection has reached its maximal size, and you are trying to
add another element (objects unit).
Thông tin thu thập tràn bộ nhớ. Những thông tin thu thập được đã đạt giới hạn lưu trữ, và có lệnh
thêm vào 1 thông tin (lỗi trong thư viện Object)

215 Arithmetic overflow error This error is reported when the result of an arithmetic operation is
outside of its supported range. Contrary to Turbo Pascal, this error is only reported for 32-bit or 64-
bit arithmetic overflows. This is due to the fact that everything is converted to 32-bit or 64-bit
before doing the actual arithmetic operation.
Lỗi tràn số học. Lỗi xảy ra khi kết quả của 1 phép toán số học nằm ngoài giới hạn hỗ trợ của biến.
Trái với Turbo Pascal, lỗi này chỉ báo cho các phép toán số học trên hệ 32-bit hoặc 64-bit. Nguyên
nhân là các dữ liệu đều được dịch sang thông tin 32-bit hoặc 64-bit trước khi thực hiện các thao tác
tính toán số học.

216 General Protection fault The application tried to access invalid memory space. This can be
caused by several problems:
Lỗi bảo vệ chung (?) Ứng dụng đã truy cập vào vùng bộ nhớ không hợp lệ. Lỗi xãy ra khi:
1. Deferencing a nil pointer
Truy cập vào 1 con trỏ Nil.
2. Trying to access memory which is out of bounds (for example, calling move with an invalid
length).
Truy cập vào vùng nhớ nằm ngoài giới hạn.

217 Unhandled exception occurred An exception occurred, and there was no exception handler
present. The sysutils unit installs a default exception handler which catches all excpetions and exits
gracefully.

219 Invalid typecast Thrown when an invalid typecast is attempted on a class using the as operator.
This error is also thrown when an object or class is typecast to an invalid class or object and a
virtual method of that class or object is called. This last error is only detected if the –CR compiler
option is used.

227 Assertion failed error An assertion failed, and no AssertErrorProc procedural variable was
installed.

You might also like