Là ngôn ngữ lập trình có tính cấu trúc và tính hệ thống: các kiểu dữ liệu đa dạng, các cấu trúc điều khiển chặt chẽ, các cấu trúc khối trong chơng trình rõ ràng,các đại lợng biến và hằng
Trang 1A Đặt vấn đề :
Hiện nay máy tính đang đợc sử dụng rộng rãi trong các cơ quan và gia đình.Nó
là một công cụ hữu hiệu giúp cho công việc nhanh hơn dễ dàng hơn Học sinh đang học tập tin học trong nhà trờng Có nhiều cuộc thi tổ chức cho học sinh giỏi tin học , trong đó có cuộc thi tin học trẻ không chuyên.Thi thực hành lập trình bằng ngôn ngữ Pascal là một phần thi hay và khó
PASCAL là ngôn ngữ lập trình bậc cao của tác giả Niklaus Wirth (giáo s ngời Thuỵ sĩ), đợc công bố vào đầu những năm 1970 Tên PASCAL là để kỉ niệm nhà Toán học ngời Pháp B Pascal
Là ngôn ngữ lập trình có tính cấu trúc và tính hệ thống: các kiểu dữ liệu đa dạng, các cấu trúc điều khiển chặt chẽ, các cấu trúc khối trong chơng trình rõ ràng,các đại lợng (biến và hằng) đã đợc khai báo để sử dụng với kiểu dữ liệu này thì không thể đem dùng lẫn với kiểu khác
PASCAL ban đầu đợc sáng tác để làm ngôn ngữ dạy học cho những ngời mới học lập trình Có tính sáng sủa, dễ hiểu, dễ đọc của nó giúp ngời mới học có thể viết một
ch-ơng trình máy tính một cách dễ dàng
Hoc sinh thờng gặp khó khăn ở phần này vì bài tập đa dạng và khó Đa số những bài tập ra theo kiểu tệp ứng dụng thực tế nên học sinh còn lúng túng để đa về dạng bài toán cơ bản, cha tìm đợc thuật toán phù hợp Để giúp học sinh hiểu rõ hơn cách làm
bài Pascal khi thi tin học không chuyên tôi đã đa ra kinh nghiệm “một số dạng bài tập lập trình Pascal có dữ liệu kiểu tệp vận dụng kiến thức mảng“ Có nhiều dạng
bài tập nhng tôi chủ yếu đa ra bài tệp kiểu tệp vận dụng kiến thức mảng 1 chiều, mảng
2 chiều
B giảI quyết vấn đề:
I,DỮ LIỆU KIỂU TỆP
1, Khỏi niệm:
Khi giải cỏc bài toỏn cần sử dụng nhiều lần về sau thỡ ta phải tổ chức dữ liệu lưu trữ trờn đĩa (dữ liệu kiểu tệp)
Cỏc số liệu được gừ vào lưu trờn một tệp như văn bản.Kết quả cũng được lưu trờn một tệp văn bản khỏc Khi kết thỳc chương trỡnh hoặc tắt mỏy thỡ dữ liệu kiểu tệp vẫn tồn
Trang 2tại trên đĩa.Các chương trình không phải kiểu tệp thì chỉ lưu tạm kết quả trên RAM nên khi tắt máy thì mất hết dữ liệu
Khai báo:
TYPE
Tên tệp:kiểu tệp; vd : var f1, f2: text
Ghi chú:
- Kiểu phần tử của tệp có thể là bất kỳ kiểu dữ liệu nào ngoại trừ kiểu tệp
- Biến tệp được khai báo băng cách sử dụng một kiểu tệp đã được định nghĩa
trước đó hoặc khai báo trực tiếp với mô tả kiểu Ví dụ:
Var
F3: File Of Char;
F4: File Of Array[1 5] Of Integer;
- Biến tệp là một biến thuộc kiểu dữ liệu tệp Một biến kiểu tệp đại diện cho một
tệp Việc truy cập dữ liệu ở một tệp được thể hiện qua các thao tác với thông số là biến tệp đại diện
2
C¸c thao t¸c trªn tÖp :
a Mở tệp mới để cất dữ liệu:
Chương trình chỉ có thể lưu lại dữ liệu vào một tệp sau khi ta làm thủ tục mở tệp mới
để lưu kết quả.Việc mở tệp được tiến hành với hai thủ tục đi liền nhau theo thứ tự: Assign(FileVar, FileName)
ReWrite(FileVar);
Trong đó:
- FileVar:biến tệp
- FileName: Ta nên đặt tên sao cho tên đó phản ánh được ý nghĩa hay bản chất, nội dung của tệp
b Ghi các giá trị vào tệp với thủ tục Write :
Thủ tục Write sẽ đặt các giá trị mới vào tệp
Cú pháp:
Write(FileVar, Item1, Item2, , ItemN);
Ví dụ: Ta cần ghi vào tệp ChuCai.txt các giá trị 1 5, thực hiện như sau:
Assign(F1, ’ChuCai.txt’);
ReWrite(F1); {mở tệp}
For a:= 1 to 5 do Write(F1, a);
Close(F); {khi ghi xong phải đóng tệp thì dữ liệu mới được lưu vào tệp}
End
c Đọc dữ liệu từ một tệp đã có :
Một chương trình muốn sử dụng các dữ liệu đã được chứa trong một têp, đầu tiên phải mở tệp đó ra để đọc, thủ tục sau nhằm mở một đọc:
Cú pháp:
Assign(FileVar, FileName);
Trang 3Sau lệnh Reset, nếu tệp không rỗng thì cửa sổ tệp bao giờ cũng trỏ vào phần tử đầu tiên của tệp và chương trình sẽ sao chép phần tử của tệp được trỏ sang biến đệm cửa
sổ Nếu ta mở một tệp chưa tồn tại trên đĩa thì sẽ có lỗi
Để đọc dữ liệu từ tệp, ta dùng thủ tục READ dạng sau:
Read(FileVar, Var1, Var2, , VarN);
Trong đó: Var1, Var2, , VarN là các biến có cùng kiểu thành phần của FileVar
Gặp lệnh này máy sẽ đọc các giá trị tại vị trí cửa sổ đang trỏ (nếu có) gán sang biến tương ứng cùng kiểu Sau đó, cửa sổ dịch chuyển sang vị trí tiếp theo và đọc giá trị cho biến khác, cứ thế đọc cho đến biến VarN READ chỉ có thể đọc giá trị của tệp để gán giá trị cho các biến
Việc đọc một phần tử của tệp cần thỏa mãn điều kiện: phần tử đó không phải là phần
tử cuối tệp tức là EOF Do đó, trước khi muốn đọc tệp và gán cho biến X, cần phải thử xem tệp đó đã kết thúc chưa bằng câu lệnh:
While Not EOF(FileVar) Do {lệnh này thường được sử dụng trước khi đọc và gán
dữ liệu từ một tệp}
Begin
Read(FileVar, X);
Xử lý biến x nếu cần;
End;
Thực hiện xong thao tác đọc hay ghi tệp ta phải đóng tệp với thủ tục sau:
Close(FileVar);
II, Mét sè dang bµi tËp d÷ liÖu kiÓu TÖP
1, D¹ng bµi tËp sö dông m¶ng 1 chiÒu
Mảng (Array) là một kiểu dữ liệu có cấu trúc bao gồm một số cố định các thành
phần có cùng kiểu, có cùng một tên chung Các phần tử của mảng được truy xuất thông qua các chỉ số
Công dụng của mảng là dùng để lưu trữ một dãy số liệu có cùng một tính chất nào
đó Ví dụ: các điểm kiểm tra một môn học nào đó của một học sinh, các giá trị của một dãy nhiều số được nhập từ bàn phím
Bài 1:: cho d·y sè gåm N sè tù nhiªn a1, a2,a3, aN .Viết chương trình in ra tổng của
N số trên
D÷ liÖu vµo cho bëi tÖp DULIEU.INP cã cÊu tróc:
-Dßng ®Çu tiªn chøa sè nguyªn N
-Dßng thø 2 chøa c¸c sè a1, a2,a3, aN c¸c sè c¸ch nhau Ýt nhÊt mét kÝ tù trèng
Trang 4Dữ liệu ra ghi vào tệp KETQUA.OUT có cấu trúc
-Một dòng trả lời kết quả của tổng
Ví dụ
DULIEU.INP KETQUA.OUT
5
4 3 6 7 8
Tong la: 28
Hướng dẫn:
-Hiểu ý nghĩa của tệp DULIEU.INP
Dũng 1 5 {được hiểu là dũng dưới cú 5 số}
Dũng 2: 4 3 6 7 8 {cỏc số cỏch nhau một dấu cỏch}
-Bài này giống nh tính tổng của mảng có 5 phần tử đợc nhập dữ liệu từ một tệp có sẵn chứ không phải nhập dữ liệu khi chạy chơng trình
-Khi viết chơng trình có 2 phần lớn:
+Phần 1: Đầu tiên ta phải đọc dữ liệu từ tệp DULIEU.INP gỏn cỏc số vào
biến Ta gán số 5 vào biến N Sau đó gán 5 số hàng dới vào mảng 1 chiều có 5 phần tử
+Phần 2: Sau khi gán các số vào mảng ta có thể xử lí giống nh bài tập mảng 1 chiều
*Lu ý: Phần 1 của các chơng trình cơ bản giống nhau và khá dễ Phần 2 là phần quan trọng và khó nhất
-Sau khi gán các số vào mảng ta có thể xử lí giống nh bài tập mảng.Phải tìm ra đợc thuật giải nhanh và tối u
-Ta ghi kết quả tổng vào tệp KETQUA.OUT
Các bớc giải:
Bớc 1: Mở một tệp pascal mới và nhập các số liệu trên vào sau đó lu với tên
DULIEU.INP
Bớc 2:Mở một tệp pascal mới và nhập chơng trình sau vào và lu lại với tên bất kì
Program tinh_tong;
Uses CRT;
Var f1,f2: Text; a:array [1 20] of integer; s,n:integer;
Begin
ClrScr;
{ Phần 1}
Assign(F1,’DULIEU.INP’); Reset(F1); {mở tệp f1 để lấy dữ liệu}
Assign(F2,’KETQUA.OUT’); Rewrite(F2); {tạo tệp f2 để ghi kết qủa }
While Not EOF(F1) Do
{kiểm tra xem đã kết thúc tệp f1 cha nếu cha kết thúc thì tiếp tục đọc dữ liệu }
Begin
Readln(F1, n); {gán số 5 cho biến n}
For i:=1 to n do read(f1,a[i]) { gán 5 số ở dòng dới vào biến mảng a[i] }
End;
{sau khi gán các số vào mảng ta có thể xử lí giống nh bài tập mảng}
{ Phần 2}
S:=0;
For i:=1 to n do s:=s+a[i];
Trang 5Write(f2,'Tong la:',s); {trả lời tổng s và lu vào tệp f2 , KETQUA.OUT} Close(f1);close(f2);
{sau khi ghi xong dữ liệu phải đóng tệp nếu không dữ liệu sẽ không đợc ghi }
Readln;
End
Bước 3: Ấn ctrl+f9 để chạy chương trình
Bước 4: mở tệp KETQUA.OUT để xem kết quả tổng.Trong tệp kết qủa
KETQUA.OUT sẽ có kết quả “Tong la:28”
Bài 1 là dạng bài tập mà số phần tử của mảng đã đợc cho trớc trong tệp DULIEU.INP
là số đầu tiên của tệp.Nếu dạng bài không cho biết số phần tử của mảng thì ta phải có thêm lệnh đếm số phần tử Sau đây là bài tơng tự bài 1 nhng không cho biết số phần tử
Bài 2:: cho dãy số gồm N số tự nhiên a1, a2,a3, aN .Viết chương trỡnh in ra tổng của
N số trờn
Dữ liệu vào cho bởi tệp DULIEU.INP có cấu trúc:
-Một dòng chứa các số a1, a2,a3, aN các số cách nhau ít nhất một kí tự trống Dữ liệu ra ghi vào tệp KETQUA.OUT có cấu trúc
-Một dòng trả lời kết quả của tổng
Ví dụ
DULIEU.INP KETQUA.OUT
4 3 6 7 8 Tong la: 28
Viết chơng trình
Program tinh_tong;
Uses CRT;
Var f1,f2: Text; a:array [1 20] of integer; s,n:integer;
Begin
ClrScr;
{ Phần 1}
Assign(F1,’DULIEU.INP’); Reset(F1); {mở tệp f1 để lấy dữ liệu}
Assign(F2,’KETQUA.OUT’); Rewrite(F2); {tạo tệp f2 để ghi kết qủa }
n:=0; {n là biến đếm số phần tử}
While Not EOF(F1) Do
Begin
n:=n+1; { cha nếu cha kết thúc tệp thì tăng n một đơn vị}
read(f1,a[i]) { gán lần lợt 5 số vào biến mảng a[i] }
End;
……
So sánh sự khác nhau của 2 đoan chơng trình
Cho biết số phần tử Không cho biết số phần tử
Trang 6While Not EOF(F1) Do
Begin
Readln(F1, n);
For i:=1 to n do read(f1,a[i])
End;
n:=0;
While Not EOF(F1) Do Begin
n:=n+1;
read(f1,a[i]) End;
Bài 3: Cầu lông
Trong buổi lễ bế mạc cuộc thi đấu cầu lông Các vận động viên đứng thành 1 hàng.Có
N vận động viên tham gia.Kết quả điểm của mỗi vận động viên thứ i là ai .Trong đó chỉ có 2 vận động viên bằng điểm nhau.Hãy tìm vị trí 2 vân động viên bằng điểm nhau và số điểm của họ
Dữ liệu vào cho bởi tệp CAULONG.INP có cấu trúc:
-Dòng đầu tiên chứa số nguyên N
-Dòng thứ 2 chứa các số a1, a2,a3, aN các số cách nhau ít nhất một kí tự trống Dữ liệu ra ghi vào tệp CAULONG.OUT có cấu trúc
-Dòng đầu tiên ghi số điểm của 2 động viên bằng điểm nhau
-Dòng thứ 2 ghi vị trí đứng của 2 động viên trong hàng
ví dụ:
CAULONG.INP CAULONG.OUT
6
8 7 5 6 7 2 72 5
Giải:
Hớng dẫn:
-Thờng khi đọc đề ta thấy dài nhng ta không nên chú ý nhiều vào yếu tố thực tế mà chủ yếu tập trung số liệu của 2 tệp ví dụ vào và ra để xem thử cần số liệu ra là gì
-Đây là bài tập mảng 1 chiều tìm 2 phần tử bằng nhau và chỉ số của 2 phần tử đó -Ta duyệt tất cả các phần tử xem 2 phần tử nào bằng nhau thi in ra giá trị và chỉ số Viết chơng trình:
Program caulong;
uses crt;
Type mang=array[1 100] of integer;
var
a,b,c:mang; ; f1,f2:text;
n,i,j:integer;
BEGIN
Assign(F1, ‘CAULONG.INP’); Reset(F1);
Assign(F2, ‘CAULONG.OUT '); Rewrite(F2);
While Not EOF(F1) Do
begin
readln(f1,n);
for i:=1 to n do read(f1,a[i]);
end;
for i:=1 to n do {bat dau duyet tung so}
for j:=i+1 to n do
if a[i]=a[j] then {nếu bằng nhau thì in ra}
Trang 7Begin
writeln(f2,a[i]:3); {in ra giá trị bằng nhau}
writeln(f2,i:3,j:3); {in ra chỉ số 2 giá trị bằng nhau}
end;
close(f1);close(f2);
readln
END
Bài 4:chất lượng
Một xưởng sản xuất sản phẩm trong N tháng Ban giám đốc muốn biết khả năng sản xuất của xởng đó.Họ muốn biết số tháng liên tục nhiều nhất mà sản phẩm liên tục tăng và các tháng đó là tháng nào?
Dữ liệu vào cho bởi tệp NN.INP có cấu trúc:
-Dòng đầu tiên chứa số nguyên N
-Dòng thứ 2 chứa các số a1, a2,a3, aN là số sản phẩm của tháng 1,2,3, N
Dữ liệu ra ghi vào tệp NN.OUT có cấu trúc
- Dòng 1 là số tháng liên tục nhiều nhất mà sản phẩm liên tục tăng
- Dòng 2 là số các tháng đó
ví dụ:
9
2 3 1 3 4 5 2 3 4 43 4 5 6
Giải:
Hớng dẫn:
- Đây là bài tập mảng 1 chiều tìm số lợng các số liên tiếp tăng nhiều nhất và chỉ số của các phần tử đó
-Ta duyệt tất cả các phần tử để tính số lợng phần tử tăng nhiều nhất và in ra giá trị số lợng và chỉ số
Viết chơng trình:
Program tang_nhieu_nhat;
uses crt;
var
n,i,j,s,bd, max :integer; a:array[1 12] of integer;
f1,f2:text;
BEGIN
clrscr;
assign(f1,'NN.INP'); reset(f1);
assign(f2,'NN.OUT'); rewrite(f2);
while not eof(f1) do
begin
readln(f1,n);
for i:=1 to n do read(f1,a[i]);
end;
Max:=0; {biến max dùng để tính số lợng phần tử tăng nhiều nhất}
For i:=1 to N do
begin
s:=0;
Trang 8for j:=i to n do
if a[j]<a[j+1] then s:=s+1 else break; {lệnh break là lệnh thoát vòng lặp}
{nếu các số tăng dần thì cộng thêm vào tổng s, ngợc lại nếu không tăng thì thóat vòng lặp}
if max<s then
begin
max:=s; bd:=j-max; {bd la chi so bat dau cua day lon nhat}
end;
end;
{so luong so thang san pham tang nhieu nhat la }
writeln(f2,max+1);
{so cac thang la}
for i:= bd to bd+max do write(f2,i:3);
close(f1); close(f2);
readln
END
B i 5: Dãy số đỉnh núi ài 5: Dãy số đỉnh núi
Dãy số đỉnh núi là dãy số có số phần tử là lẻ, số chính giữa là số lớn nhất(đỉnh núi)
và phía bên trái và bên phải của số đỉnh núi các số giảm dần (xuống núi).Kiểm tra 1 dãy số có phải là dãy số đỉnh núi không?
Dữ liệu vào cho bởi tệp DINHNUI.INP có cấu trúc:
-Một dòng chứa các số a1, a2,a3, aN các số cách nhau ít nhất một kí tự trống Dữ liệu ra ghi vào tệp DINHNUI.OUT có cấu trúc
-Một dòng trả lời kết quả là dãy số đỉnh núi hay không là dãy số đỉnh núi
Ví dụ
3 6 7 8 6 5 2 dãy số đỉnh núi
4 5 7 9 6 7 3 không là dãy số đỉnh núi
Giải:
Hớng dẫn:
- Đây là bài tập mảng 1 chiều không cho biết số phần tử
-Nếu n chẵn thì không phải
-Nếu n lẻ thì ta lấy phần tử ở chính giữa làm trung tâm (có chỉ số là (n-1)/2+1 ) sau đó xét xem
+ Dãy các phần tử từ a1 đến phần tử ở chính giữa có mấy phần tử tăng dần (bien t) + Dãy các phần tử từ phần tử ở chính đến giữa aN có mấy phần tử giảm dần (bien s) -Nếu t=s trả lời là dãy số đỉnh núi ngợc lại thì không phải
Viết chơng trình
Program daydinhnui;
Uses CRT;
Var f1,f2: Text; a:array [1 20] of integer; s,n:integer;
Begin
ClrScr;
Assign(F1,’ DINHNUI.INP’); Reset(F1);
Assign(F2,’ DINHNUI.OUT’); Rewrite(F2);
n:=0;
Trang 9While Not EOF(F1) Do
Begin
n:=n+1;
read(f1,a[i])
End;
if (n mod 2 = 0) then write(f2,'khong la day dinh nui'); { n chẵn}
else { nếu n lẻ}
begin
s:=0; t:=0;
for i:=1 to n do
begin
for i:=1 to (n div 2)+1 do
if a[i]<a[i+1] then s:=s+1 else break;
if s=((n div 2)+1) then
begin
for i:= ((n div 2)+1) to n do
if a[i]>a[i+1] then t:=t+1 else break;
end;
if t=s then write(f2,'la day dinh nui ') else
write(f2,'khong la day dinh nui');
end;
end;
close(f1); close(f2);
readln
end
2, Dạng bài tập sử dụng mảng 2 chiều
Bài 1: giao hữu thể thao
Trong 1 cuộc thi đấu giao hữu thể thao có 2 đội A,B mỗi đội tham gia N môn thi đấu Sau khi thi đấu xong 2 đội xếp thành M hàng để công bố kết quả.Các vân động viên
đứng theo thứ tự i các môn thi đấu.Để tao sự thân thiện các hàng của 2 đội xếp xen kẽ nhau Đội A xếp hàng số lẻ, đội B xếp hàng số chẵn.Hãy tính tổng số điểm của từng môn của từng đội và tổng điểm của từng đội?
Dữ liệu vào cho bởi tệp GIAOHUU.INP có cấu trúc:
-Dòng đầu tiên chứa 2 số nguyên N,M
-N dòng tiếp theo mỗi dòng chứa M số nguyên dơng là số điểm của từng vận
động viên tơng ứng môn i
Dữ liệu ra ghi vào tệp GIAOHUU.OUT có cấu trúc là
-M dòng đầu là tổng số điểm của từng môn của từng đội
Trang 10-Dòng cuối cùng là tổng điểm của từng đội
ví dụ:
GIAOHUU.INP GIAOHUU.OUT
3 4
1 2 1 3
2 1 2 2
5 1 3 4
2 5
4 3
8 5
14 13 Hớng dẫn:
-Đây là bài tập mảng 2 chiều tính tổng các số hàng lẻ và hàng chẵn sau đó lại tính tổng của cột lẻ và cột chẵn
Viết chơng trình:
PROGRAM giaohuu;
uses crt;
var
i,j,k,m,n,l,s,t,tl,tc:integer;
f1,f2:text; a:array[1 100,1 100] of integer;
begin
clrscr;
assign(f1,'GIAOHUU.INP');
reset(f1);
assign(f2,'GIAOHUU.OUT');
REWRITE(F2);
while not eof(f1)do
begin
readln(f1,n,m); {n là số hàng,m là số cột}
for i:=1 to n do
for j:=1 to m do read(f1,a[j,i]);
end;
for i:=1 to n do
begin
s:=0; t:=0; j:=1; k:=2;
{s là tổng các số hàng lẻ; t tổng các số hàng chẵn; j là chỉ số cột lẻ, k là chỉ số cột chẵn }
while (j <=m) and (k<=m) do
begin
s:=s+a[j,i]; t:=t+a[k,i];
j:=j+2; k:=k+2;
end;
writeln(s:3,t:3);
tl:=tl+s; { tl là tổng cột lẻ}
tc:=tc+t; { tc là tổng cột chẵn}
end;
write(f2,tl:3, tc:3);
close(f1); close(f2);
readln
end