CÁC BÀI TẬP VỀ MẢNG 1 CHIỀU VÀ 2 CHIỀU
BÀI TẬP 1
Nhập vào một số n
(5<=n<=10) và n phần tử của dãy a, 1<ai<100 (có kiểm
tra dữ liệu khi nhập).
a)
In ra các phần tử
là số nguyên tố của
dãy.
b)
Tính ước chung lớn nhất
của tất cả
các phần tử của
dãy.
c)
Tính biểu thức sau:
d)
Sắp xếp dãy tăng
dần và in ra dãy sau sắp xếp.
HƯỚNG DẪN
Ta nên chia chương trình thành các chương trình con, mỗi chương trình thực
hiện một yêu cầu.
Ngoài ra ta cũng viết
thêm các hàm kiểm tra nguyên tố,
hàm mũ, hàm UCLN để thực
hiện các yêu cầu đó.
Chương trình như sau:
Khai báo dữ liệu:
uses crt;
var n : integer;
a : array[1..10] of integer; {n<=10 nên mảng
có tối đa 10 phần
tử}
Thủ tục nhập
dữ liệu, có kiểm
tra khi nhập.
procedure nhap;
var i : integer;
begin
clrscr;
write('NHAP VAO SO PHAN TU N = ');
repeat
readln(n);
if (5<=n) and (n<=10) then break; {nếu
thoã mãn thì dừng vòng lặp}
writeln('Khong hop le (5<=n<=10). Nhap lai!!!'); {ngược lại thì báo lỗi}
until false;
writeln('NHAP VAO N PHAN TU (1<ai<100)');
for i := 1 to n do begin
write('a',i,'=');
repeat
readln(a[i]);
if (1<a[i]) and (a[i]<100) then break;
writeln('Khong hop le. Nhap lai!!!');
until false;
end;
end;
function ngto(n :
integer): boolean; {hàm kiểm tra nguyên tố,
xem giải thích ở phần
trên}
var i : integer;
begin
ngto := false;
if n < 2 then exit;
for i := 2 to round(sqrt(n)) do
if n mod i = 0 then exit;
ngto := true;
end;
Thủ tục in các số
nguyên tố của
một mảng
procedure inngto;
var i :integer;
begin
writeln('CAC PHAN TU NGUYEN TO TRONG DAY:');
for i := 1 to n
do
{duyệt qua mọi phần
tử từ 1 đến
n}
if ngto(a[i]) then writeln(a[i]);
{nếu ai là nguyên tố thì in ra}
end;
function UCLN(a,b:
integer): integer;
var r : integer;
begin
while b<>0 do begin
r := a mod b;
a := b;
b := r;
end;
UCLN := a;
end;
Thủ tục tính UCLN của
các phần tử của
một mảng
procedure TinhUC;
var i,u : integer;
begin
u :=
a[1];
{u là UCLN của các phần
tử từ 1 đến
i}
for i := 2 to n do u := UCLN(u,a[i]); {là
UCLN của các phần tử từ 1 đến i-1 và ai}
writeln('UCLN cua ca day la:',u);
end;
function hammu(a :
real; n : integer): real; {hàm mũ tính an}
var s : real; i : integer;
begin
s := 1;
for i := 1 to n do s := s * a;
hammu := s;
end;
Thủ tục tính tổng
các phần tử có lấy
mũ:
procedure tong;
var s : real; i : integer;
{s phải khai báo là số thực để tránh tràn số}
begin
s := 0;
for i := 1 to n do s := s + hammu(a[i],i); {s := s + (ai)i}
writeln('Tong can tinh:',s:10:0);
end;
Thủ tục sắp
xếp tăng dần
các phần tử của
một mảng:
procedure sxep;
var i,j,tg : integer;
begin
for i := 1 to n-1 do
for j := i + 1 to n do
if a[i] > a[j] then begin
tg := a[i]; a[i] := a[j]; a[j] := tg;
end;
writeln('DAY SAU KHI SAP XEP TANG DAN:');
for i := 1 to n do writeln(a[i]);
end;
Chương trình chính: lần lượt
gọi từng thủ tục
BEGIN
nhap;
inngto;
tinhuc;
tong;
sxep;
END.
BÀI TẬP 2
Tìm phần tử nhỏ
nhất, lớn nhất
của một mảng
(cần chỉ ra cả vị trí của phần
tử).
HƯỚNG DẪN
Giả sử phần
tử min cần tìm là phần
tử k. Ban đầu ta cho k=1. Sau đó cho i chạy
từ 2 đến n, nếu
a[k] > a[i] thì rõ ràng a[i] bé hơn, ta gán k bằng i. Sau khi duyệt toàn bộ
dãy thì k sẽ là chỉ số của phần
tử min. (Cách tìm min này đơn giản vì từ vị
trí ta cũng suy ra được
giá trị).
procedure timmin;
var i, k : integer;
begin
k := 1;
for i := 2 to n do
if a[k] > a[i] then k := i;
writeln('Phan tu nho nhat la a[',k,']=',a[k]);
end;
Tìm max cũng tương tự,
chỉ thay dấu so sánh.
procedure timmax;
var i, k : integer;
begin
k := 1;
for i := 2 to n do
if a[k] < a[i] then k := i;
writeln('Phan tu lon nhat la a[',k,']=',a[k]);
end;
Chú ý:
1. Nếu áp dụng với
mảng 2 chiều thì cũng
tương tự, chỉ
khác là để duyệt
qua mọi phần tử của mảng 2 chiều
thì ta phải dùng 2 vòng for. Và vị trí một phần
tử cũng gồm
cả dòng và cột.
Ví dụ 1. Tìm phần tử
nhỏ nhất và lớn
nhất của mảng
2 chiều và đổi chỗ
chúng cho nhau:
procedure exchange;
var
i,j,i1,j1,i2,j2,tg : integer;
begin
i1 := 1; j1 := 1; {i1,j1 là vị trí phần
tử min}
i2 := 1; j2 := 1; {i2,j2 là vị trí phần
tử max}
for i := 1 to m do
for j := 1 to n do begin
if a[i1,j1] > a[i,j] then begin {so sánh tìm min}
i1 := i; j1 := j; {ghi nhận
vị trí min mới}
end;
if a[i2,j2] < a[i,j] then begin {so sánh tìm max}
i2 := i; j2 := j; {ghi nhận vị
trí max mới}
end;
end;
tg := a[i1,j1]; a[i1,j1] := a[i2,j2]; a[i2,j2] := tg; {đổi
chỗ}
end;
2. Nếu cần tìm phần
tử lớn nhất
/ nhỏ nhất hoặc
sắp xếp 1 dòng (1 cột)
của mảng 2 chiều
thì ta cũng coi dòng (cột) đó như 1 mảng
1 chiều. Chẳng hạn
tất cả các phần
tử trên dòng k đều có dạng
chỉ số là a[k,i] với
i chạy từ 1 đến
n (n là số cột).
Ví dụ 2. Tìm phần tử lớn nhất của
dòng k và đổi chỗ
nó về phần tử đầu dòng.
procedure timmax(k
: integer);
var i, vt, tg : integer;
begin
vt := 1; {vt là vị trí của
phần tử min dòng k}
for i := 1 to n do
if a[k,i] > a[k,vt] then vt := i; {các phần
tử dòng k có dạng a[k,i]}
tg := a[k,1]; a[k,1] := a[k,vt]; a[k,vt] := tg;
end;
Ví dụ 3. Sắp xếp
giảm dần cột
thứ k.
procedure sapxep(k:
integer);
var i,j,tg : integer;
begin
for i := 1 to m-1 do {mỗi cột
có m phần tử, vì bảng
có m dòng}
for j := i+1 to m do
if a[i,k] > a[j,k] then begin {các phần
tử cột k có dạng
a[i,k]}
tg := a[i,k]; a[i,k] := a[j,k]; a[j,k] := tg;
end;
end;
BÀI TẬP 3
Tìm các phần tử thoả
mãn 1 tính chất gì đó.
HƯỚNG DẪN
Nếu tính chất cần
thoả mãn là cần kiểm
tra phức tạp (chẳng
hạn: nguyên tố, hoàn thiện,
có tổng chữ số bằng 1 giá trị cho trước…)
thì ta nên viết một
hàm để kiểm tra 1 phần
tử có tính chất đó không.
Còn tính chất cần
kiểm tra đơn giản
(chẵn / lẻ, dương
/ âm, chia hết, chính phương…)
thì không cần.
Sau đó ta duyệt
qua các phần tử từ đầu đến
cuối, phần tử
nào thoả mãn tính chất đó thì
in ra.
Ví dụ 1. In ra các số chính phương
của một mảng:
Để kiểm tra n có chính phương không, ta lấy căn n, làm tròn
rồi bình phương và so sánh với
n. Nếu biểu thức
sqr(round(sqrt(n))) = n là true thì n là chính phương.
Vậy để in các phần
tử chính phương ta viết:
for i := 1 to n do begin
if sqr(round(sqrt(a[i]))) = a[i] then writeln(a[i]);
Ví dụ 2. In ra các số hoàn thiện
từ 1 đến n:
Để kiểm tra số có hoàn thiện
ta dùng hàm tổng ước
(đã có ở phần đầu).
for i := 1 to n do begin
if tongus(i) = i then writeln(i);
Ví dụ 3. In ra các phần tử của mảng chia 3 dư
1, chia 7 dư 2:
for i := 1 to n do begin
if (a[i] mod 3=1) and (a[i] mod 7=2) then writeln(a[i]);
Ví dụ 4. In ra các số có 3 chữ số, tổng chữ số bằng 20, chia 7 dư
2.
Ta dùng hàm tổng chữ số đã có ở trên:
for i := 100 to 999 do begin {duyệt qua mọi số có 3 chữ số}
if (tongcs(i)=20) and (i mod 7=2) then writeln(i);
Chú ý: Nếu áp dụng với
mảng 2 chiều thì cũng
tương tự, chỉ
khác là để duyệt
qua mọi phần tử của mảng 2 chiều
thì ta phải dùng 2 vòng for.
Ví dụ, để in các phần
tử nguyên tố của
1 mảng 2 chiều:
for i := 1 to m do begin
for j := 1 to n do begin
if ngto(a[i,j]) then writeln(a[i,j]);
BÀI TẬP 4
Nhập và in mảng 2 chiều
dạng ma trận (m dòng, n cột).
HƯỚNG DẪN
Để nhập các phần tử của mảng 2 chiều
dạng ma trận, ta cần
dùng các lệnh sau của
unit CRT (nhớ phải
có khai báo user crt ở đầu
chương trình).
GotoXY(a,b): di chuyển con trỏ màn hình đến
vị trí (a,b) trên màn hình (cột
a, dòng b). Màn hình có 80 cột và 25 dòng.
whereX: hàm cho giá
trị là vị trí cột
của con trỏ màn hình.
whereY: hàm cho giá
trị là vị trí dòng của
con trỏ màn hình.
Khi nhập 1 phần tử
ta dùng lệnh readln nên con trỏ màn hình sẽ xuống
dòng, do đó cần quay lại dòng của
bằng lệnh GotoXY(j * 10, whereY -1 ), nếu ta muốn mỗi
phần tử của
ma trận ứng với
10 cột màn hình.
procedure nhap;
var i,j : integer;
begin
clrscr;
write('Nhap m,n = '); readln(m,n);
for i := 1 to m do begin
for j := 1 to n do begin
write('A[',i,',',j,']='); readln(a[i,j]); {nhập
xong thì xuống dòng}
gotoXY(j*10,whereY-1); {di chuyển về dòng trước, vị
trí tiếp theo}
end;
writeln; {nhập xong 1 hàng thì xuống dòng}
end;
end;
Để in bảng dạng ma trận
thì đơn giản hơn,
với mỗi dòng ta sẽ
in các phần tử
trên 1 hàng rồi xuống
dòng:
procedure inbang;
var i,j : integer;
begin
for i := 1 to m do begin
{viết các phần tử của hàng i }
for j := 1 to n do write(a[i,j]:6); {mỗi
phần tử chiếm
6 ô để căn phải
cho thẳng cột và không khít nhau}
writeln; {hết 1 hàng thì xuống
dòng}
end;
end;
Không có nhận xét nào:
Đăng nhận xét