Vòng Lặp
I. Vòng lặp có số bớc lặp các định
Trớc hết chúng ta xét ví dụ sau :
Giả sử ta phải viết ra màn hình các số từ 0 đến 24, mỗi số chiếm 1 dòng
Việc này có thể thực hiện bằng 25 lệnh Writeln
Writeln(0)
Writeln(1)
..........
Writeln(24)
Cách viết này rõ ràng là dài dòng và tẻ nhạt trong khi nó có quy luật
Chúng ta có thể thay thế bằng lệnh Writeln(I) trong đó I là một biến nguyên bất kì nhận giá trị từ
0..24
FOR I:=0 TO 24 DO Writeln(I)
Vòng lặp này cho I chạy từ 0 đến 24 với mỗi giá trị của I, máy sẽ thực hiện công việc viết sau chữ
DO (làm), ở đây là Writeln(I)
Mẫu viết tổng quát :
FOR Biến_điều_khiển:=Giá_trị_đầu TO Giá_trị_cuối DO <việc>
Và ngợc lại ta có mẫu :
FOR Biến_điều_khiển:=Giá_trị_đầu DOWNTO Giá_trị_cuối DO <việc>
II. Vòng lặp có số bớc lặp không xác định
Có 2 kiểu vòng lặp không xác định
REPEAT WHILE <biểu thức Boolean>DO
<công việc>; BEGIN
UNTIL <Biểu thức Boolean>; <công việc>;
END;
Trong lệnh REPEAT ... UNTIL ... máy tính sẽ
lặp đi lặp lại chu kì sau : thực hiện <công việc> cho
đến khi <biểu thức Boolean> có giá trị TRUE. Giữa
REPEAT và UNTIL không cần dùng BEGIN và END
Còn trong vòng lặp WHILE ... DO máy tính sẽ lặp đi lặp lại chu kì sau : chừng nào <biểu thức
Boolean> có giá trị TRUE thì đi thực hiện <công việc> đợc đặt giữa BEGIN và END
Cả hai vòng lặp đều có số lần lặp không xác định trớc. Cần phải lu ý là trong khi thực hiện <công
việc> lặp, ta phải có một lệnh làm thay đổi một biến trong biểu thức Boolean để thay đổi giá trị biểu
thức nhằm dừng vòng lặp lại vì nếu không vòng lặp sẽ chạy mãi không dừng
VD : Tính A = 1 + 1/2 + 1/3 + ... + 1/N
Dùng REPEAT và cho I chạy thuận
A:=0;I:=1;
REPEAT
A := A + 1/I;
I := I + 1;
UNTIL I>N;
Writeln('Tổng = ',A:10:8);
Dùng WHILE và cho I chạy ngợc
A:=0;I:=N;
WHILE I>0 DO
BEGIN
A := A + 1/I;
I := I - 1;
1
END;
Bài 1:{ Nhập số nguyên dơng N. Sau đó nhập N số nguyên dơng. Tìm số lớn nhất,
nhỏ nhất và tính trung bình của các phần tử}
var i,a,n:integer;{Khai báo i,a,n kiểu integer}
max,min,tong:integer;{Khai báo max,min,tong kiểu integer}
begin
write('N = ');readln(n);{Nhập N}
min:=maxint;{Gán min bằng maxint}
max:=0;tong:=0;{Gán max và tổng bằng 0}
for i:=1 to n do{Cho i chạy từ 1 đến n}
begin
write('So thu ',i,' : ');readln(a);{Đọc số thứ i vào biến a}
if min>a then min:=a;{Nếu min>a thì gán min bằng a}
if max<a then max:=a;{Nếu max<a thì gán max bằng a}
inc(tong,a);{Tăng tổng lên a đơn vị}
end;
writeln('Max = ',max);{Xuất max}
writeln('Min = ',min);{Xuất min}
writeln('Trung binh : ',tong/n:0:2);{Xuất trung bình}
readln;
end.
Bài 2:
{ Năm nay con a tuổi, cha b tuổi. Dùng WHILE tính xem sau mấy năm nữa hoặc trớc
đây mấy năm tuổi cha gấp đôi tuổi con
Hớng dẫn
Nếu a*2=b thì ở hiện tại
Nếu a*2<b thì ở tơng lai
Nếu a*2>b thì ở trong quá khứ}
var a,b,so:integer;{a,b,so kiểu integer}
begin
write('Nhap tuoi con, tuoi cha : ');readln(a,b);{Nhập tuổi con, tuổi cha}
if a=b*2 then write('Hien tai tuoi cha gap doi con'){Nếu a=b thì ở hiện tại}
else if a*2<b then{Ngợc lại nếu a*2<b thì}
begin
so:=0;{Gán so bằng 0}
while (a+so)*2<b+so do inc(so);{Trong khi (a+so)*2<b+so thì tăng số lên}
writeln('Sau ',so,' nam nua tuoi cha gap doi tuoi con');{Xuất ra sau "so" nam nua}
end
else
begin
so:=0;{Gán so bằng 0}
while (a-so)*2>b-so do inc(so);{Trong khi (a-so)*2<b-so thì tăng số lên}
writeln('Truoc day ',so,' nam tuoi cha gap doi tuoi con');{Xuất ra truoc do "so" nam}
end;
readln;
end.
2
Bài 3:
{ Nhập 2 số nguyên dơng. Tìm ớc chung lớn nhất và bội chung nhỏ nhất của 2 số đó
Hớng dẫn
UCLN(a,b) = UCLN(a,a-b) nếu a>b
= UCLN(a,b-a) nếu b>a
BCNN(a,b) = a*b div UCLN(a,b)}
var a,b:integer;{a,b kiểu integer}
tich:longint;{tich kiểu longint}
begin
write('A, B = ');readln(a,b);{Đọc a,b}
tich:=a*b;{Gán tich bằng a*b}
while a<>b do{Trong khi a<>b thì}
if a>b then a:=a-b else b:=b-a;{Nếu a>b thì gán a=a-b ngợc lại gán b=b-a}
writeln('UCLN = ',a);{Xuất UCLN (a hoặc b)}
writeln('BCNN = ',tich div b);{Xuất BCNN}
readln;
end.
Bài 4:
{ Dùng REPEAT ... UNTIL in ra màn hình bảng nhân N (từ Nx1 tới Nx10)}
var i,n:integer;{Khai báo i,n kiểu integer}
begin
write('N = ');readln(n);{Đọc N}
i:=0;{Gán i bằng 0}
repeat
inc(i);{Tăng i}
writeln(n:2,' x ',i:2,' = ',n*i:3);{Xuất n,i,n*i}
until i=10;
readln;
end.
Bài 5:{ In ra màn hình các giá trị sin, cos, tan của các góc 0, 5, 10, 15 ... 90
Hớng dẫn
Dùng hàm sin(x) cos(x) nhng phải đổi số độ sang radian (X có đơn vị là radian) bằng
CT Radian = pi*Số độ / 180
Tính tang dựa vào CT tan=sin/cos nhng nhớ tan90 không tồn tại}
const pi=3.14;{Khai báo hằng pi=3.14}
var i:integer;{i kiểu integer}
x:real;{x kiểu real}
begin
for i:=0 to 18 do{Cho i chạy từ 0 đến 18 (i*5 tơng ứng số độ)}
begin
x:=pi*i*5/180;{Đổi i*5 độ sang x radian}
write('Sin ',i*5:2,' = ',sin(x):0:5,' ');{Xuất sin}
write('Cos ',i*5:2,' = ',cos(x):0:5,' ');{Xuất cos}
if i<>18 then write('Tan ',i*5:2,' = ',sin(x)/cos(x):0:5){Nếu i<>18 thì xuất sin(x)/cos(x)}
else write('Tan 90 khong ton tai');{Ngợc lại xuất Tan không tồn tại}
writeln;
end;
readln;
3
end.
Bài 6:
{ Biết N! = 1x2x3x..xN
In ra màn hình giai thừa các số từ 1 tới 12
1! = 1
2! = 2
3! = 6
Hớng dẫn
Phải dùng kiểu longint để tính vì số rất lớn }
uses crt;
var
i,n:longint;{Khai báo i,n kiểu longint}
begin
clrscr;{Xoá màn hình}
n:=1;{Gán n bằng 1}
for i:=1 to 12 do{Cho i chạy từ 1 đến 12}
begin
n:=n*i;{Gán n bằng n*i}
writeln(i,' ! = ',n);{Xuất ra N}
end;
readln;
end.
Bài 7:
{ Nhập số nguyên dơng N (N<10).
a. In ra màn hình các chỉnh hợp lặp chập 3 của N phần tử
b. In ra màn hình các chỉnh hợp không lặp chập 3 của N phần tử.
c. In ra màn hình các tổ hợp chập 3 của N.
Hớng dẫn
Chỉnh hợp lặp :
i=1->N j=1->N k=1->N : Xuất i,j,k
Chỉnh hợp không lặp :
i=1->N j=1->N k=1->N :
Nếu i<>j<>k thì xuất
Tổ hợp
i=1->N-2 j=i+1->N-1 k=j+1->N : Xuất i,j,k}
var
i,j,k,n:byte;{i,j,k,n kiểu byte}
begin
write('N = ');readln(n);{Đọc N}
writeln('Cac chinh hop lap :');
for i:=1 to n do{Cho i chạy từ 1 đến N}
for j:=1 to n do{Cho j chạy từ 1 đến N}
for k:=1 to n do{Cho k chạy từ 1 đến N}
write(i,j,k,' ');
readln;
writeln('Cac chinh hop khong lap :');
for i:=1 to n do{Cho i chạy từ 1 đến N}
for j:=1 to n do{Cho j chạy từ 1 đến N}
for k:=1 to n do{Cho k chạy từ 1 đến N}
4
if(i<>j)and(j<>k)and(i<>k)then write(i,j,k,' ');{Nếu i<>j<>k thì xuất mới xuất i,j,k}
readln;
writeln('Cac to hop :');
for i:=1 to n-2 do{Cho i chạy từ 1 đến N-2}
for j:=i+1 to n-1 do{Cho j chạy từ i+1 đến N-1}
for k:=j+1 to n do{Cho k chạy từ j+1 đến N}
write(i,j,k,' ');
readln;
end.
Bài 8:
{ In ra màn hình bảng cửu chơng từ 1->10
Hớng dẫn
Dùng hàm GOTOXY(x,y) để di chuyển tới toạ độ cột x dòng y trên màn hình
Ta chia chiều ngang màn hình thành 5 cột, chiều dọc màn hình thành 2 hàng. Từ hàng
2..11 ta in bảng 1,2,3,4,5. Từ hàng 13..22 ta in bảng 6,7,8,9,10
Khi ta tới hàng i x j thì toạ độ bắt đầu sẽ là
y = j+1 nếu i<6
= j+12 nếu i>=6
x = ((i-1)mod 5)*16+1;}
uses crt;
var i,j,x,y:byte;{i,j,x,y kiểu byte}
begin
clrscr;{Xoá màn hình}
for i:=1 to 10 do{Cho i chạy từ 1 đến 10 (i là bảng)}
for j:=1 to 10 do{Cho j chạy từ 1 đến 10}
begin
if i<6 then y:=j+1 else y:=j+12;{Tính y theo CT ở phần thuật toán}
x:=((i-1)mod 5)*16+1;{Tính x theo CT ở phần thuật toán}
gotoxy(x,y);{Nhảy tới vị trí x,y}
write(i,' x ',j,' = ',i*j);
end;
readln;
end.
Bài 9:
{ Viết chơng trình giải bài toán :
Trăm trâu, trăm bó cỏ
Trâu đứng ăn năm
Trâu nằm ăn ba
Lụ khụ trâu già 3 con 1 bó
Hỏi mỗi loại có mấy con
Hớng dẫn
Điều kiện trên thoả khi :
100 = (std*5+stn*3+stg3)
và std+stn+stg3*3=100
Trong đó
std : Số trâu đứng <=20
stn : Số trâu nằm <=33
stg3 : Số bó cỏ trâu già ăn<=33}
5