Một số bài tập về mảng 1 chiều - 2 chiều


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:
us­es crt;
var n : in­te­ger;
      a : ar­ray[1..10] of in­te­ger; {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.
pro­ce­dure nhap;
var i : in­te­ger;
be­gin
            clrscr;
            write('NHAP VAO SO PHAN TU N = ');
            re­peat
                        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}
            un­til false;
            writeln('NHAP VAO N PHAN TU (1<ai<100)');
            for i := 1 to n do be­gin
                        write('a',i,'=');
                        re­peat
                                    readln(a[i]);
                                    if (1<a[i]) and (a[i]<100) then break;
                                    writeln('Khong hop le. Nhap lai!!!');
                        un­til false;
            end;
end;
func­tion ng­to(n : in­te­ger): boolean; {hàm kiểm tra nguyên tố, xem giải thích ở phần trên}
var i : in­te­ger;
be­gin
            ng­to := false;
            if n < 2 then ex­it;
            for i := 2 to round(sqrt(n)) do
                        if n mod i = 0 then ex­it;
            ng­to := true;
end;
Thủ tục in các số nguyên tố của một mảng
pro­ce­dure in­ng­to;
var i :in­te­ger;
be­gin
            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 ng­to(a[i]) then writeln(a[i]);                 {nếu ai là nguyên tố thì in ra}
end;
func­tion UCLN(a,b: in­te­ger): in­te­ger;
var r : in­te­ger;
be­gin
            while b<>0 do be­gin
                        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
pro­ce­dure Tin­hUC;
var i,u : in­te­ger;
be­gin
            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;
func­tion ham­mu(a : re­al; n : in­te­ger): re­al; {hàm mũ tính an}
var s : re­al; i : in­te­ger;
be­gin
            s := 1;
            for i := 1 to n do s := s * a;
            ham­mu := s;
end;
Thủ tục tính tổng các phần tử có lấy mũ:
pro­ce­dure tong;
var s : re­al; i : in­te­ger; {s phải khai báo là số thực để tránh tràn số}
be­gin
            s := 0;
            for i := 1 to n do s := s + ham­mu(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:
pro­ce­dure sx­ep;
var i,j,tg : in­te­ger;
be­gin
            for i := 1 to n-1 do
                        for j := i + 1 to n do
                                    if a[i] > a[j] then be­gin
                                                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
BE­GIN
            nhap;
            in­ng­to;
            tin­huc;
            tong;
            sx­ep;
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ị).
pro­ce­dure tim­min;
var i, k : in­te­ger;
be­gin
            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.
pro­ce­dure tim­max;
var i, k : in­te­ger;
be­gin
            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:
pro­ce­dure ex­change;
var i,j,i1,j1,i2,j2,tg : in­te­ger;
be­gin
            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 be­gin
                                    if a[i1,j1] > a[i,j] then be­gin {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 be­gin {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.
pro­ce­dure tim­max(k : in­te­ger);
var i, vt, tg : in­te­ger;
be­gin
            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.
pro­ce­dure sapx­ep(k: in­te­ger);
var i,j,tg : in­te­ger;
be­gin
            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 be­gin {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 be­gin
         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 be­gin
         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 be­gin
         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 be­gin {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 be­gin
     for j := 1 to n do be­gin
         if ng­to(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 us­er crt ở đầu chương trình).
Go­toXY(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 Go­toXY(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.
pro­ce­dure nhap;
var i,j : in­te­ger;
be­gin
            clrscr;
            write('Nhap m,n =  '); readln(m,n);
            for i := 1 to m do be­gin
                        for j := 1 to n do be­gin
                                    write('A[',i,',',j,']=');  readln(a[i,j]); {nhập xong thì xuống dòng}
                                    go­toXY(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:
pro­ce­dure in­bang;
var i,j : in­te­ger;
be­gin
            for i := 1 to m do be­gin                           {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