Tải bản đầy đủ (.docx) (49 trang)

tai lieu boi duong tin

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (270.58 KB, 49 trang )

<span class='text_page_counter'>(1)</span><div class='page_container' data-page=1>

<b>giíi thiƯu</b>


Từ năm học 2006-2007, Bộ Giáo dục và Đào tạo đã quyết định đa Tin học
thành một môn học ở các trờng phổ thông. Đây là một quyết định rất đúng đắn
và kịp thời.


Hiện nay, mặc dù đã có nhiều tài liệu Tin học để giáo viên và học sinh
triển khai hoạt động dạy học nhng vẫn còn thiếu một số tài liệu tham khảo khác
nh: sách bài tập, tài liệu nâng cao phục vụ công tác bồi dỡng học sinh giỏi...


Từ kinh nghiệm giảng dạy bộ môn, đồng thời thấy đợc nhu cầu của thực
tiễn, chúng tôi mạnh dạn biên soạn tài liệu này nhằm giúp giáo viên và học sinh
triển khai tốt hơn trong hoạt động dạy học bộ môn Tin học, đặc biệt trong cơng
tác bồi dỡng học sinh giỏi.


Néi dung tµi liƯu gåm cã 4 phÇn.


Phần 1: Một số kinh nghiệm, nhằm trình bày một số kinh nghiệm trong
việc hớng dẫn học sinh làm bài, nộp bài và chiến lợc đạt điểm cao nhất có thể.


Phần 2: Một số chuyên đề, nhằm trình bày một số vấn đề cơ bản trong
việc bồi dỡng học sinh giỏi nh: Phơng pháp đánh dấu phần tử; Số nguyên tố,
thuật toán trong hình học phẳng, thuật toán đệ quy quay lui, thuật toán quy
hoạch động...


Phần 3: Một số bài tập đề nghị. Phần này giới thiệu một số bài tập đơn
giản nhằm giúp ngời đọc tự rèn luyện hoặc chọn làm các bài tập cho học sinh khi
giảng dạy các kiến thức cơ bản


Phần 4: Một số bài tập tuyển chọn. Phần này giới thiệu một số bài tập tơng
đối khó, đợc chọn làm đề thi học sinh giỏi qua các năm. Sau mỗi đề bài tập


chúng tơi tích hợp cả chơng trình gợi ý nhằm giúp bạn đọc có điều kiện tham
khảo. Các bài tập này có những thuật tốn điển hình thờng đợc sử dụng trong các
kỳ thi học sinh giỏi trong các năm tiếp theo.


Với thời gian có hạn, chắc chắn tài liệu này sẽ khơng tránh khỏi những
thiếu sót. Chúng tơi sẽ rất biết ơn sự đóng góp ý kiến quý báu từ phía bạn đọc để
tài liệu này ngày càng hồn thiện hn.


<i>Đồng Hới, ngày 20 tháng 11 năm 2009</i>


Lê Thủy Thạch


<b>Mt s kinh nghim trong việc hớng dẫn học sinh làm</b>
<b>bài, nộp bài và chiến lợc đạt điểm cao nhất có thể.</b>


<b>I - Híng dÉn học sinh trình bày và nộp bài thi</b>


<i><b>1 - Tạo th mơc chøa bµi thi</b></i>


- Khởi động NC.


</div>
<span class='text_page_counter'>(2)</span><div class='page_container' data-page=2>

Việc làm này nhằm mục đích tạo một th mục chứa file bài làm của học
sinh để học sinh tránh việc chép nhầm file bài làm.


- Tạo trong th mục THI một file TP.BAT, có nội dung là đờng dẫn đến
TURBO.EXE. Thông thờng là C:\TP\BIN\TURBO.EXE


Việc làm này nhằm mục đích thuận tiện trong khởi động Turbo Pascal. Để
khởi động Turbo, chỉ cần đa con trỏ đến TP.bat và Enter.



Khi thực hiện tạo một file chơng trình Pascal, file đó sẽ nằm trong th mục
THI đợc tạo ra trờn.


<i><b>2 - Trình bày bài thi và thao tác lập trình</b></i>


<i>a- Cần phải tách riêng thao tác tạo kiểu dữ liệu và khai báo biến:</i> Nhiều giáo
viên thờng hớng dẫn học sinh khai báo biến mảng nh sau:


Var a:array[1..10] of integer;


Cách này là không tiện, vì thông thờng khi lập trình giải quyết một bài
toán, ta thờng sử dụng chơng trình con và truyền tham sè.


Khi đó ta có khai báo : tên chơng trình con(tên biến: tên kiểu dữ liệu);
Nếu là bin mng, ta khụng th vit :


tên chơng trình con (a :array[1..10] of integer) ;


<i>b-Nếu dữ liệuvào đợc cho trong file, phải đặt tên file trong phần const:</i> Ví dụ:
Const fi= ‘BAI1.INP’;


Giám khảo có nhiều file dữ liệu vào với tên file có dạng: XXX.IN?, trong
đó dấu ? là các số thuộc 0...9.


Khi chấm bài, giám khảo chỉ việc thay ký tự cuối cúng trong tên file và
thực hiện chơng trình để thu kết quả.


Nếu thí sinh để tên file trong thân chơng trình, chẳng hạn:
assign(f,‘bai1.inp’), điều này buộc giám khảo phải tìm tên file trong chơng trình
của học sinh. Việc làm này có hai điều bất lợi:



Thứ nhất: gây ức chế cho giám khảo khi phải di chuyển con trỏ nhiều lần
để thay đổi tên file dữ liệu vào.


Thø hai: Cã thÓ trong quá trình di chuyển con trỏ, giám khảo sẽ bấm nhầm
phím làm hỏng file chơng trình của thí sinh.


<i>c-Nu bài yêu cầu xuất dữ liệu ra file, kết thúc chơng trình khơng đợc đặt</i>
<i>readln;</i>


Nếu thí sinh cố tình đặt readln để dừng màn hình, giám khảo có thể cho
rằng chơng trình thực hiện cha xong và khơng cho điểm bài này. Giám khảo có
thể khơng bấm Enter mà bấm CTRL+Break, khi đó xem nh chơng trình bị ngắt
giữa chừng, kt qu cú th khụng c ghi ra file.


<i>d-Đầu chơng trình bắt buộc phải có dẫn biên dịch </i> {$R+}


ý nghĩa của {$R+} là: Kiểm tra tràn phạm vi của biÕn: Range check


Nếu có tích hợp {$R+}, Turbo Pascal sẽ tự động kiểm tra tràn phạm vi,
tuy nhiên thời gian thực hiện chơng trình sẽ lớn hơn. Nếu khơng đặt thỡ Turbo
Pascal khụng kim tra.


Chẳng hạn, ta có khai báo: a: array [1..10] of integer;
vµ cã lƯnh: For i:=1 to 11 do a[i]:=i;


Nếu khơng tích hợp {$R+} thì ta khơng thể phát hiện đợc lỗi tràn phạm vi
của biến mảng a.


<i>e-Cần lu file ngay từ đầu, sau đó lu tiếp trong q trình làm bài. </i>


Mục đích là tránh mất chơng trình khi mất điện giữa chừng.
<i>f-Đặt tên file bài làm và tên file dữ liệu vào đúng với yêu cầu của đề bài</i>


</div>
<span class='text_page_counter'>(3)</span><div class='page_container' data-page=3>

<i>g-Làm từng nào biên dịch từng đó.</i>


Mục đích nhằm dễ dàng phát hiện lỗi chính tả của chơng trình. Nếu xuất
hiện lỗi thì lỗi đó chỉ có thể do những lệnh vừa mới gõ sinh ra.


<i><b>3 - Sao chÐp bµi vµ nép bµi</b></i>


<i>a-Mở khóa đĩa mềm. Đặt đĩa vào ổ đĩa. Chép file trong th mục đã tạo ở trên vào</i>
<i>đĩa mềm.</i>


Cần cẩn thận trong thao tác chép, vì có thể tồn tại 2 file có phần tên giống
nhau nhng khác phần mở rộng: PAS và BAK. File PAS là file chơng trình cần
chép, File BAK là file backup, file cũ sau mỗi lần ta sửa đổi và lu lại sửa đổi.
<i>b-Khóa đĩa trớc khi nộp đĩa cho giám thị.</i>


Khi đĩa đã đợc khóa, ta không thể lu thông tin lên đĩa.


Việc làm này tránh đợc tình huống có thể bị giám thị làm hng file chng
trỡnh.


<i>c-Chờ giám thị in bài và kiểm tra bài thi trên giấy.</i>


Sau khi np bi, giỏm th phi thực hiện in bài thi ra giấy để làm chứng và
phịng tránh trờng hợp hỏng đĩa.


Thí sinh cần phải dị lại bài của mình. Điều này giúp thí sinh tránh đợc
tình huống giám thị có thể in bài của học sinh khác cho mình. Nếu bài in và bài


làm trên đĩa khác nhau, xem nh bài làm của học sinh khơng hợp lệ, thí sinh chắc
chắn bị hủy kết quả thi.


<i>d-Ký xác nhận và nhờ một học sinh khác ký x¸c nhËn</i>


Mục đích của ký xác nhận nhằm khẳng định tờ giấy in bài làm là đúng
của mình và tránh xảy ra tiêu cực giữa thí sinh dự thi và giám thị có thể đổi bài.


<i><b>4 - Các bớc để hồn thành một chơng trình</b></i>


Phơng pháp tổng qt để giải bài toán tin học là một hệ thống các bớc có
tính ổn định nhằm giúp ngời học có thể tìm ra thuật giải, biễu diễn đợc dữ liệu và
từ đó viết đợc chơng trình.


Phơng pháp tổng quát để giải bài toán tin học bao gồm các bớc sau:


<i><b>a- Xác định bài toán </b></i>


Mọi bài toán trong Tin học đều có thể diễn đạt theo một sơ đồ chung
A B


A: gọi là INPUT (thông tin vào)
B: gọi là OUTPUT (thông tin ra)


: gọi là chơng trình đợc tạo từ các câu lệnh cơ bản của máy
cho phép biến A thành B.


<i>Ví dụ:</i> Cho hai số tự nhiên a,b. Tìm USCLN của chúng
<i>Xác định thông tin vào:</i><b> </b>Hai số tự nhiên a, b



<i>Xác định thông tin ra: </i>Số tự nhiên d thoả mãn d là ớc của a và d là ớc của b và d
là lớn nhất trong tập ớc chung đó.


<i>Xác định các thao tác chế biến thông tin:</i>


Xây dựng một tập hữu hạn các phép tính cho phép tính đợc d từ a và b


<i><b>b-Tìm cấu trúc dữ liệu biễu diễn bài toán</b></i>


Vic la chon CTDL tuỳ thuộc vào vấn đề phải giải quyết. Sau đó là chọn
cách biểu diễn thơng tin. Việc này tuỳ thuộc vào các thao tác thực hiện trên kiểu
dữ liu.


<i>Các lu ý khi chọn cấu trúc dữ liệu </i>


+CTDL phải biểu diễn đợc đầy đủ các thông tin nhập và xuất của bài toán.
+CTDL phải phù hợp với các thao tác của thuật toán mà ta lựa chọn
gii quyt bi toỏn.


</div>
<span class='text_page_counter'>(4)</span><div class='page_container' data-page=4>

<i><b>c-Tìm thuật toán</b></i>


Thut toỏn là một hệ thống chặt chẽ và rõ ràng các quy tắc nhằm xác định
một dãy các thao tác trên một dãy các đối tợng sao cho sau một hữu hạn các bớc
thực hiện các thao tác, ta đạt đợc mục tiêu định trớc.


<i><b>d- LËp tr×nh</b></i>


Lập trình là dùng một ngơn ngữ cụ thể nào đó để diễn tả thuật toán, cấu
trúc dữ liệu thành các câu lệnh để máy tính có thể thực hiện đợc và giải quyết
đúng bài tốn mà ngời lập trình mong muốn.



<i>Phát triển chơng trình bằng cách tinh chế từng bớc:</i> Tinh chế từng bớc là phơng
pháp khoa học có hệ thống giúp ta phân tích các thuật tốn, cấu trúc dữ liệu từ
đó viết thành chơng trình.


<i><b>e-Chạy thử, thay đổi kiểm tra chơng trình .</b></i>


<i>Chạy thử:</i> Một chơng trình đã viết cha chắc đã chạy đợc trên máy để cho kết quả
mong muốn vì vậy địi hỏi phải chạy thử chơng trình. Kỹ năng tìm lỗi, sửa lỗi,
điều chỉnh cũng là một kỹ năng của ngời lập trình.


<i>Lu ý khi x©y dùng c¸c bé test</i>


Nên khởi đầu bằng các bộ test nhỏ nhng chứa các giá trị đặc biệt
Làm nhiều b test nhng a dng.


Phải có các bộ test có kích thớc lớn.


<i>Ví dụ:</i> Khi viết chơng trình giải phơng trình ax2<sub> + bx + c = 0. ta phải xây dựng</sub>


các bộ test nh sau:


a b c


0 0 0


0 0 1


1 2 1



2 5 3


Ngoài ra, cần xây dựng bộ test có giá trị lớn nh: 1 32767 32766
<i>Lu ý: </i>Chơng trình chạy qua một số bộ test cha hẳn là chơng trình đúng.


<i><b>f/ Thay đổi chơng trình</b></i>


Một chơng trình đã viết xong, đã chạy tốt cha hẳn là quá trình lập trình đã
kết thúc. Ta phải sửa đổi nó theo một hớng nào đó để đáp ứng yêu cầu mới.
Ph-ơng pháp tinh chế từng bớc giúp ta thuận lợi trong việc sửa đổi chPh-ơng trình.
<b>II - Chiến lợc đoạt điểm</b>


-Phải tham gia giải hết tất cả các bài của đề ra mặc dù có thể kết quả của
chơng trình khơng đúng. Điều này nhằm đoạt đợc một ít điểm hoặc tránh đợc
điểm 0. Cần chú ý phải biên dịch thành cơng.


-Tìm những trờng hợp dễ để xuất kết quả


-Đối với những bài tốn có trả lời là YES/NO (hoặc 1/0), nếu giải khơng
đợc thì nên xuất một giá trị YES (hoặc 1), khi đó có thể gở đợc 1/3 số điểm của
câu (mẹo này tính hiệu quả không cao, đặc biệt trong các kỳ thi HSG Quốc gia).


<b>B - Một số chuyên đề</b>


<b>I - Đánh dấu phần tử đợc chọn</b>


<i><b>1-ý tëngchung</b></i>


Kỹ thuật đánh dấu phần tử là một trong những kỹ thuật nhằm giúp cho
ng-ời lập trình tạo đợc những thuật tốn đơn giản để giải quyết vấn đề đặt ra.



Để đánh dấu phần tử đợc chọn, ta khai báo một mảng A gồm nhiều phần
tử, với A[i]=true theo nghĩa i là phần tử đợc chọn, A[i]=false theo nghĩa i là phần
tử không đợc chọn.


<i><b>2-ứng dụng PP đánh dấu trong bài toán sắp xếp dóy s</b></i>


</div>
<span class='text_page_counter'>(5)</span><div class='page_container' data-page=5>

Bài toán: Cho một dÃy số gồm N phần tử (1<=N<=32766). Các phần tử ai


ca dóy là các số nguyên dơng, đôi một khác nhau (1<=ai <=32766). Hóy sp


xếp dÃy số tăng dần.


Ta thng s dụng thuật giải sắp xếp đơn giản để giải quyết bài toán này
nh sau:


For i:=1 to N-1 do
For j:=i+1 to N do


If a[i]<a[j] then
Begin
t:=a[i];
a[i]:=a[j]
a[j]:=t;
End;


Chơng trình biểu diễn của thuËt to¸n:


<b>const fi='sap1.inp';</b>
<b> fo='sap1.out';</b>



<b>type mmc=array[1..32766] of integer;</b>
<b>var f:text;</b>


<b> i,j,n,t:integer;</b>


<b> a:^mmc; ti:longint;</b>
<b>begin</b>


<b>ti:=meml[0:$46c];</b>
<b>new(a);</b>


<b>assign(f,fi);reset(f);</b>
<b>readln(f,n);</b>


<b>for i:=1 to n do read(f,a^[i]);</b>
<b>close(f);</b>


<b>for i:=1 to n-1 do</b>
<b> for j:=i+1 to n do</b>


<b> if a^[i]>a^[j] then</b>
<b> begin</b>


<b> t:=a^[i]; a^[i]:=a^[j]; a^[j]:=t;</b>
<b> end;</b>


<b>assign(f,fo);rewrite(f);</b>
<b>writeln(f,n);</b>



<b>for i:=1 to n do write(f,a^[i],' ');</b>
<b>close(f);</b>


<b>dispose(a);</b>


<b>writeln('Thoi gian thu hien ',(meml[0:$46c]-ti)/18.21:8:5);</b>
<b>readln;</b>


<b>end.</b>


Khi N bé, thuật toán trên là chấp nhận đợc. Tuy nhiên, trong nhiều trờng
hợp N lớn, chẳng hạn N=32766 phần tử, khi đó độ phức tạp của thuật toán là
O(N2<sub>) máy sẽ thực hiện trong rất nhiều thời gian mới sắp xếp đợc dãy s. (vi</sub>


N=20000, thời gian thực hiện khoảng 14 giây)


gii quyết đợc bài toán này khi N lớn trong một khoảng thời gian rất
nhỏ, ta sử dụng kỹ thuật đánh du phn t.


</div>
<span class='text_page_counter'>(6)</span><div class='page_container' data-page=6>

nhau. Đối với bài toán sắp xếp có phần tử trùng nhau ta không thể sử dụng
ph-ơng pháp này.


<i>Phơng pháp:</i>
<i>Dữ liệu: </i>


Sử dụng một mảng A gồm 32766 phần tử, các phần tử có kiểu boolean.
<i>ý nghĩa: </i>


A[i]=true có nghĩa i là phần tử có trong dÃy, A[i]=false có nghĩa i là phần
tử không có trong dÃy.



<i>Thuật toán:</i>


+ Khi ng mi giỏ tr của A[] là False {Giống nh giả sử ban đầu mọi
phần tử đều không thuộc dãy số}


+ Đọc từng phần tử của dãy số, giả sử số thứ j của dãy là X, ta đánh dấu
phần tử A[X]=true {Xác nhận số X thuộc dãy số}. Thực hiện đánh dấu cho đến
khi đọc hết dãy số. Khi đó ta thu đợc một mảng A[] trong đó A[i]=true tại các
chỉ số i có giá trị bằng giá trị các phần tử trong dãy số.


+ Duyệt từ đầu mảng đến cuối mảng, nếu vị trí vào có giá trị True thì ta
xuất chỉ số đó ra. Kết quả ta đợc một dóy s c sp xp tng dn.


Chơng trình mẫu:


<b>const fi='sap1.inp';</b>
<b> fo='sap2.out';</b>


<b>type mmcb=array[1..32766] of boolean;</b>
<b>var f:text; </b>


<b>n:word; </b>
<b>b:mmcb; </b>
<b>ti:longint;</b>
<b>procedure doc;</b>
<b>var i,x:word;</b>
<b>begin</b>


<b>fillchar(b,sizeof(b),false);</b>


<b>assign(f,fi);</b>


<b>reset(f);</b>
<b>readln(f,n);</b>
<b>for i:=1 to n do</b>
<b> begin</b>


<b> read(f,x);</b>
<b> b[x]:=true;</b>
<b> end;</b>


<b>close(f);</b>
<b>assign(f,fo);</b>
<b>rewrite(f);</b>
<b>writeln(f,n);</b>


<b>for i:=1 to 32766 do</b>


<b> if b[i]=true then write(f,i,' ');</b>
<b>end;</b>


<b>begin</b>


<b>ti:=meml[0:$46c];</b>
<b>doc;</b>


<b>writeln('TG=',(meml[0:$46c]-ti)/18.21:8:4);</b>
<b>readln;</b>


</div>
<span class='text_page_counter'>(7)</span><div class='page_container' data-page=7>

<i>NhËn xÐt: </i>



Khi N=20000 chơng trình thực hiện trong 0.05giây. Chơng trình này chạy
nhanh gấp 280 lần so với chơng trình đã viết theo thuật tốn đơn giản trên.


Rõ ràng, kỹ thuật đánh dấu phần tử có ý nghĩa rất quan trọng trong việc
giảm thời gian thực hiện chơng trình.


<i><b>3 - ứng dụng PP đánh dấu trong bài toán lọc dữ liệu</b></i>


Lọc dữ liệu là một vấn đề có ý nghĩa to lớn trong xử lý thông tin. ý nghĩa
thực tiễn của lọc dữ liệu là nhằm loại bỏ các dữ liệu d thừa, không cần thiết, từ
đó dễ dàng thu đợc thơng tin cần tìm.


Bài toán: Cho một dãy số gồm N phần tử (1<=N<=32766), trong đó các
phần tử có kiểu nguyên nằm trong [1..32766]. Hãy trích ra từ dãy số trên một tập
con gồm nhiều phần tử nhất sao cho các phần tử đôi một khác nhau.


Ta thờng giải quyết bài toán trên theo thuật toán đơn giản nh sau:
+ Dùng một mảng B[] để lu các giá trị tìm đợc


+ Đọc từng phần tử của dãy số đã cho, giả sử số đọc đợc là X. Kiểm tra
xem X đã có trong B[] hay cha.


+ Nếu cha có trong B[] thì đặt vào cuối cùng của B[]


Khi N bé, thuật toán trên có thể chấp nhận đợc. Tuy nhiên, trong nhiều
tr-ờng hợp N rất lớn, chẳng hạn N=32766 phần tử, khi đó độ phức tạp của thuật
tốn là O(N2<sub>) máy sẽ thực hiện trong rất nhiều thời gian để lấy từng phần tử</sub>


trong dãy để so sánh với các phần tử trong tập B[].



Để giải quyết đợc bài toán này khi N lớn trong một khoảng thời gian rất
nhỏ, ta sử dng k thut ỏnh du phn t.


<i>Phơng pháp:</i>
<i>Dữ liệu: </i>


Sử dụng một mảng B gồm 32766 phần tử, các phần tư cã kiĨu boolean.
<i>ý nghÜa: </i>


B[i]=true cã nghÜa i là phần tử ta sẽ chọn, B[i]=false có nghĩa i là phần tử
ta không chọn.


<i>Thuật toán:</i>


+ Khi ng mi giỏ trị của B[] là False {Giống nh giả sử ban đầu ta cha
chọn phần tử nào cả}


+ Đọc từng phần tử của dãy số, giả sử số thứ j của dãy là X, ta đánh dấu
phần tử B[X]=true {Xác nhận số X đợc chọn}. Thực hiện đánh dấu cho đến khi
đọc hết dãy số. Khi đó ta thu đợc một mảng B[] trong đó B[i]=true tại các chỉ số
i mà ít nhất i xuất hiện một lần trong dãy đã cho


+ Duyệt từ đầu mảng đến cuối mảng B[], nếu vị trí nào có giá trị True thì
ta xuất chỉ số đó ra. Kết quả ta đợc một tập cỏc phn t cn tỡm.


Chơng trình mẫu:


<b>const fi='tc.in1';</b>
<b> fo='tc.ou4';</b>


<b> nn=60000;</b>
<b>var n,a:word; </b>


<b>f:text;</b>


<b>k:array[1..nn] of boolean;</b>
<b>procedure doctep;</b>


<b>var i:word;</b>
<b>begin</b>


<b> assign(f,fi); </b>
<b>reset(f);</b>


</div>
<span class='text_page_counter'>(8)</span><div class='page_container' data-page=8>

<b> for i:=1 to n do</b>
<b> begin</b>


<b> read(f,a);</b>
<b> k[a]:=true;</b>
<b> end;</b>


<b> close(f);</b>
<b>end;</b>


<b>procedure xulivaxuat;</b>
<b>var i,d:word;</b>


<b>begin</b>


<b> assign(f,fo); </b>


<b>rewrite(f);</b>


<b> d:=0;</b>


<b> for i:=1 to nn do</b>


<b> if k[i]=true then d:=d+1;</b>
<b> writeln(f,d);</b>


<b> for i:=1 to nn do</b>


<b> if k[i]=true then write(f,' ',i);</b>
<b> close(f);</b>


<b>end;</b>
<b>BEGIN</b>
<b>doctep;</b>
<b>xulivaxuat;</b>
<b>END.</b>


<i>Nhận xét:</i> Chơng trình này chạy nhanh gấp khoảng 300 lần so với chơng trình đã
viết theo thuật tốn đơn giản trên.


<i><b>4-ứng dụng PP đánh dấu trong bài tốn tìm giao của hai tập hợp</b></i>


Xác định giao của hai tập hợp là một bài toán quan trọng trong toán học.
Trong thực tiễn, phép giao nhằm giúp ta xác định đợc nhóm thụng tin chung nht
ca nhiu nhúm thụng tin.


<i>Bài toán: </i>



Cho 2 tệp văn bản TEP1.INP và TEP2.INP chứa N số tự nhiên trong
khoảng 1..M có thể trùng nhau. Hãy tạo TEP3.OUT chứa các số có mặt trong cả
hai tệp TEP1.INP và TEP2.INP sao cho các số đơi một khác nhau.


DLV DLR


Dßng 1: Sè N (1<=N<=32766)
Dßng 2: N sè ai (1<=ai<=M<=32766)


Dòng 1 chứa các số tìm đợc
<i>Ví dụ</i>


TEP1.INP TEP2.INP TEP3.OUT
7


5 7 1 3 5 2 7
6


3 5 1 2 1 19


1 3 2 5


Ta thờng giải quyết bài toán trên theo thuật toán đơn giản nh sau:
+ Dùng mảng A[] để lu các số trong tệp 1


+ Dùng mảng B[] để lu các số trong tệp 2


+ LÊy tõng phÇn tư Xi trong A[], so sánh với lần lợt từng phần tử Yj trong



B[]. Nu Xi có trong B[] thì đem Xi đặt vào mảng C[].


+ Lấy từng phần tử Yj trong B[], so sánh với lần lợt từng phần tử Zk trong


C[]. Nu Yj có trong C[] thì đem Yj đặt vào mảng D[].


</div>
<span class='text_page_counter'>(9)</span><div class='page_container' data-page=9>

Khi N bé, thuật tốn trên có thể chấp nhận đợc. Tuy nhiên, trong nhiều
tr-ờng hợp N rất lớn, chẳng hạn N=32766 phần tử, khi đó độ phức tạp của thuật
toán là O(2N2<sub>) máy sẽ thực hiện trong rất nhiều thời gian để lấy từng phần tử</sub>


trong A[] để so sánh với các phần tử trong B[].


Để giải quyết đợc bài toán này khi N lớn trong một khoảng thời gian rất
nhỏ, ta sử dụng kỹ thut ỏnh du phn t nh sau:


<i>Phơng pháp:</i>
<i>Dữ liệu: </i>


Sử dơng hai m¶ng A vµ B gåm 32766 phÇn tư, các phần tử có kiĨu
boolean.


<i>ý nghÜa: </i>


A[i]=true cã nghÜa i lµ phần tử thuộc tệp 1, A[i]=false có nghĩa i là phần tử
không thuộc tệp 1.


B[i]=true có nghĩa i là phần tử thuộc tệp 2, B[i]=false có nghĩa i là phần tử
không thuộc tệp 2.


<i>Thuật toán:</i>



+ Khi ng mi giỏ tr của A[] và B[] là False


+ Đọc từng phần tử của tệp 1, giả sử số đọc đợc của dãy là X, ta đánh dấu
phần tử A[X]=true {Xác nhận số X thuộc tệp 1}. Thực hiện đọc và đánh dấu
cho đến khi đọc hết tệp 1.


Khi đó ta thu đợc một mảng A[] trong đó A[i]=true tại các chỉ số i mà ít
nhất i xuất hiện một lần trong tệp 1.


+ Đọc từng phần tử của tệp 2, giả sử số đọc đợc của dãy là Y, ta đánh dấu
phần tử B[Y]=true {Xác nhận số Y thuộc tệp 2}. Thực hiện đọc và đánh dấu
cho đến khi đọc hết tệp 2.


Khi đó ta thu đợc một mảng B[] trong đó B[i]=true tại các chỉ số i mà ít
nhất i xuất hiện một lần trong tệp 2.


+ Duyệt từ đầu mảng đến cuối mảng A[] B[], nếu tại vị trí nào mà A[i] và
B[i] có giá trị True thì ta xuất chỉ số đó ra. Kết quả ta đợc một tập các phần tử
cần tỡm.


<i>Chơng trình mẫu:</i>


<b>const f1='tep1.inp';</b>
<b> f2='tep2.inp';</b>
<b> f3='tep3.out';</b>


<b>type mmc=array[1..32767] of boolean;</b>
<b>var n,i,j,a:longint; </b>



<b>k:mmc; </b>
<b>f,fi:text;</b>
<b>procedure doctep;</b>
<b>begin</b>


<b> assign(f,f1); </b>
<b>reset(f);</b>


<b> readln(f,n);</b>
<b> for i:=1 to n do</b>
<b> begin</b>


<b> read(f,a);</b>
<b> k[a]:=true;</b>
<b> end;</b>


</div>
<span class='text_page_counter'>(10)</span><div class='page_container' data-page=10>

<b>procedure xulivaxuat;</b>
<b>begin</b>


<b> assign(fi,f3);</b>
<b> rewrite(fi);</b>
<b> assign(f,f2);</b>
<b> reset(f);</b>
<b> readln(f,n);</b>
<b> for i:=1 to n do</b>
<b> begin</b>


<b> read(f,a);</b>


<b> if k[a]=true then</b>


<b> begin</b>


<b> write(fi,' ',a);</b>
<b> k[a]:=false;</b>
<b> end;</b>


<b> end;</b>
<b> close(f);</b>
<b> close(fi);</b>
<b>end;</b>


<b>BEGIN</b>
<b>doctep;</b>
<b>xulivaxuat;</b>
<b>end.</b>


<i>Nhận xét:</i> Chơng trình này chạy nhanh gấp 400 lần so với chơng trình đã viết
theo thuật tốn đơn giản trên.


<b>II - Số nguyên tố</b>


<i><b>1-Khái niệm về số nguyên tố</b></i>


n gin và dễ nhớ, ta có thể hiểu: Số nguyên tố là số tự nhiên lớn hơn
1 và chỉ có hai c s l 1 v chớnh nú.


Chẳng hạn: Số 5 là số nguyên tố. Số 9 không phải là số nguyªn tè


<i><b>2-Một số bài tốn liên quan đến số ngun t</b></i>



<i>Bài 1:</i> Viết chơng trình nhập một số nguyên dơng X (2<=X<=2147483647). HÃy
kiểm tra xem X có phải là số nguyên tố hay không?


<i>Phng phỏp: </i>Duyt cỏc s i t 2 đến X-1. Nếu tồn tại số i mà X chia hết cho i thì
kết luận đợc X khơng phải số nguyên tố.


<i>ThuËt to¸n:</i>


+NhËp sè X;
+Phai:=true;


+For i:=2 to X-1 do


If X mod i = 0 then phai=false;


+If phai=true then xuat(X la so nguyen to)
Ngợc lại xuat(X khong phai la so nguyen to );
<i>Chơng trình:</i>


<b>var x,i:longint;</b>
<b>phai:boolean;</b>
<b>begin</b>


<b>writeln('Hay nhap vao mot so nguyen > 2 ');</b>
<b>readln(X);</b>


<b>phai:=true;</b>


</div>
<span class='text_page_counter'>(11)</span><div class='page_container' data-page=11>

<b> if x mod i=0 then phai:=false;</b>



<b>if phai=false then writeln(X,' Khong phai la so NT ')</b>
<b>else writeln(X,' La so nguyen to ');</b>


<b>readln;</b>
<b>end.</b>


<i>NhËn xÐt:</i>


-Chơng trình đợc viết theo thuật tốn ở trên sẽ thực hiện chậm khi X lớn.
-Để cải tiến chơng trình ta có một số nhận xét sau:


+ Với X bất kỳ ta ln có: X khơng chia hết cho bất kỳ số nào trong
các số từ (X div 2)+1 đến X-1


+ Khi tån t¹i mét sè i thuéc [2.. X div 2] mµ X chia hÕt cho i thì
chắc chắn X là số nguyên tố.


-Trờn c s hai nhn xột trờn ta xut:


+ Chỉ lặp lại thực hiƯn kiĨm tra c¸c sè i thc [2..X div 2]


+ NÕu tån t¹i sè i thuéc [2.. X div 2] mà X chia hết cho i thì dừng
lặp.


<i>Thuật toán cải tiến</i>


Bớc 1: Nhập: X


Bớc 2: Khởi tạo: Phai:=true; i:=2;
Bíc 3: LỈp: (i<= X div 2) vµ (phai =true)



If X mod i = 0 then phai=false; Qua bíc 4;
If X mod i <> 0 then i:=i+1; Quay l¹i Bíc 3:
Bíc 4: Tr¶ lêi: If phai=true then xuat(‘X la so nguyen to)


Ngợc lại xuat(X khong phai la so nguyen to );
<i>Chơng trình cải tiến</i>


<b>var x,i:longint; </b>
<b>phai:boolean;</b>
<b>begin</b>


<b>writeln('Hay nhap vao mot so nguyen > 2 ');</b>
<b>readln(X);</b>


<b>phai:=true;</b>
<b>i:=2;</b>


<b>while (i<=x div 2) and (phai=true) do</b>
<b> begin</b>


<b> if x mod i=0 then </b>
<b>begin </b>


<b>phai:=false;</b>


<b>writeln('uoc so=',i);</b>
<b>end;</b>


<b> i:=i+1;</b>


<b> end;</b>


<b>if phai=false then writeln(X,' Khong phai la so nguyen to ')</b>
<b>else writeln(X,' La so nguyen to ');</b>


<b>readln;</b>
<b>end.</b>


<i>Bài 2:</i> Viết chơng trình đếm tất cả các số nguyên tố từ 1..N. (2<=N<=32766).
Phơng pháp:


</div>
<span class='text_page_counter'>(12)</span><div class='page_container' data-page=12>

<i>Tht to¸n</i>


Bíc 1: Nhập: N


Bớc 2: Lặp: với mỗi x  [2..N] ta thùc hiƯn c¸c bíc sau:
Bíc 3: Khëi t¹o: Phai:=true; i:=2;


Bíc 4: Lặp: (i<= X div 2) và (phai =true)


If X mod i = 0 then phai=false;


If X mod i <> 0 then i:=i+1; Quay lại Bớc 4:
Bớc 5: Đếm: If phai=true then dem:=dem+1;


Quay lại bớc 3;
Bớc 6: Trả lời: xuat(dem)
<i>Chơng trình: </i>


<b>var n,x,i,dem:integer;</b>


<b> phai:boolean;</b>


<b>begin</b>


<b>writeln('Hay nhap vao mot so nguyen N > 2 ');</b>
<b>readln(N);</b>


<b>dem:=0;</b>


<b>For x:=2 to n do</b>
<b>Begin</b>


<b> phai:=true;</b>
<b> i:=2;</b>


<b> while (i<=x div 2) and (phai=true) do</b>
<b> begin</b>


<b> if x mod i=0 then phai:=false;</b>
<b> i:=i+1;</b>


<b> end;</b>


<b>if phai=true then dem:=dem+1;</b>
<b>end;</b>


<b>writeln('Co ',dem, ' so nguyen to ');</b>
<b>readln;</b>


<b>end.</b>



<i>Nhận xét:</i>


-Với mỗi số X ta phải lặp X div 2 lÇn phÐp kiĨm tra. VËy cã N sè X, ta
phải lặp lại N*(X div 2) lần. Độ phức tạp cđa tht to¸n xÊp xØ O(N2<sub>).</sub>


-Trong lập trình giải tốn, rất ít khi ngời ta ra một đề bài tìm các số
nguyên tố mà thờng là: việc xác định số nguyên tố là một bài toán phụ cho một
bài tốn khác. Chính vì vậy việc xác định số nguyên tố phải sử dụng ít thời gian
thực hiện nhất cú th.


-Để cải tiến thuật toán, ta có nhận xÐt quan träng: Víi bÊt kú sè nguyªn X
(X>1), ta luôn có bội số của X (khác X) không phải là số nguyên tố.


<i>Phơng pháp cải tiến:</i>


-Gi s ta ó xác định đợc X là số nguyên tố, khi đó ta đánh dấu False cho
tất cả các số là bội của X. Sau này khi xét đến các số đã đợc đánh dấu False, ta
khơng cần kiểm tra số đó nữa.


-Để thực hiện đợc ta sử dụng một mảng gồm 32767 phần tử có kiu
Boolean


<i>Thuật toán cải tiến:</i>


Bớc 1: Nhập: N.


Bớc 2: Khởi tạo: Mảng B[] bằng True.


</div>
<span class='text_page_counter'>(13)</span><div class='page_container' data-page=13>

NÕu B[X] = True th×



Đánh dấu tất cả các bội của X thành False (B[K*X]:=False;
Quay lại Bớc 3:


Bớc 4: Đếm:


dem:=0;


Duyt t u n cui mng B[].
If B[X]=true then dem:=dem+1;
Bc 5: Tr li: xuat(dem);


<i>Chơng trình c¶i tiÕn:</i>


<b>const nn=32766;</b>


<b> fo='daynt.out';</b>


<b>type mmb=array[1..nn] of boolean;</b>


<b>var f:text; n,dem:integer; b:mmb; t:longint;</b>
<b>procedure lapmangnt;</b>


<b>var i,j:longint;</b>
<b>begin</b>


<b>write('Nhap mot so nguyen N>2 ');</b>
<b>readln(n);</b>


<b>t:=meml[0:$46c];</b>



<b>for i:=1 to n do b[i]:=true;</b>
<b>for i:=2 to n do</b>


<b> if b[i]=true then</b>


<b> for j:=2 to n div i do</b>
<b> b[i*j]:=false;</b>
<b>assign(f,fo);</b>


<b>rewrite(f);</b>
<b>dem:=0;</b>


<b>for i:=2 to n do</b>


<b> if b[i] then dem:=dem+1;</b>
<b>writeln(f,dem);</b>


<b>close(f);</b>
<b>end;</b>


<b>begin</b>


<b>lapmangnt;</b>


<b>writeln('Thoi gian =',(meml[0:$46c]-t)/18.21:8:4);</b>
<b>readln;</b>


<b>end.</b>



<i>Nhận xét:</i> -Thuật toán và chơng trình có vẻ nh phức tạp và khó hiểu hơn chơng
trình khi cha cải tiến. Tuy nhiên chơng trình này thực hiện nhanh hơn xấp xỉ 100
lần so với khi cha cải tiến.


<i>Bài 3:</i> Viết chơng tr×nh in ra tƯp NT.OUT tÊt c¶ các số nguyên tè tõ 1..N.
(2<=N<=32766). CÊu tróc cđa NT.OUT nh sau:


Dịng1: Ghi số M là số lợng số ngun tố tìm đợc


Dịng 2: Ghi M số ngun tố tìm đợc. các số ghi cách nhau bởi dấu cách.


<i>Nhận xét:</i> Thực ra, đây chỉ là một phát triển nhỏ của bài 2 đã giải ở trên. Chỉ
khác là ở chỗ dữ liệu xuất ra không chỉ là số lợng mà còn bao gồm cả các số
nguyên tố. Hơn nữa dữ liệu đợc xuất ra file thay vì xuất ra mn hỡnh.


<i>Phơng pháp:</i>


</div>
<span class='text_page_counter'>(14)</span><div class='page_container' data-page=14>

Bớc 5: Trả lời:


xuat(dem)


Duyt từ đầu đến cuối mảng B[]
If B[X]=true then xuat(X);
<i>Chơng trình</i>


<b>const nn=32766;</b>


<b> fo='daynt.out';</b>


<b>type mmb=array[1..nn] of boolean;</b>



<b>var f:text; n,dem:integer; b:mmb; t:longint;</b>
<b>procedure lapmangnt;</b>


<b>var i,j:longint;</b>
<b>begin</b>


<b>write('Nhap mot so nguyen N>2 ');</b>
<b>readln(n);</b>


<b>t:=meml[0:$46c];</b>


<b>for i:=1 to n do b[i]:=true;</b>
<b>for i:=2 to n do</b>


<b> if b[i]=true then</b>


<b> for j:=2 to n div i do b[i*j]:=false;</b>
<b>assign(f,fo);</b>


<b>rewrite(f);</b>
<b>dem:=0;</b>


<b>for i:=2 to n do</b>


<b> if b[i] then dem:=dem+1;</b>
<b>writeln(f,dem);</b>


<b>for i:=2 to n do</b>



<b> if b[i] then write(f,i,' ');</b>
<b>close(f);</b>


<b>end;</b>
<b>begin</b>


<b>lapmangnt;</b>


<b>writeln('Thoi gian =',(meml[0:$46c]-t)/18.21:8:4);</b>
<b>readln;</b>


<b>end.</b>


<b>III-Số nhị phân</b>


<i><b>1-Một số khái niệm liên quan số nhị phân</b></i>


<i>a-H m thp phõn: </i>


Dùng 10 ký hiệu 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 để biểu diễn mọi giá trị.


Phép cộng thêm 1 đơn vị vào một giá trị ta đợc một giá trị là số đứng tiếp
sau. Chẳng hạn 2+1=3. Khi thêm 1 đơn vị vào số tận cùng trong dãy (số 9) ta sử
dụng ký hiệu 10 để biểu diễn giá trị thứ mời.


<i>b-Hệ đếm nhị phân</i>


Dùng 2 ký hiệu 0, 1 để biểu diễn mọi giá trị.


Phép cộng thêm 1 đơn vị vào một giá trị ta đợc một giá trị là số đứng tiếp


sau. Chẳng hạn 0+1=1. Khi thêm 1 đơn vị vào số tận cùng trong dãy (số 1) ta sử
dụng ký hiệu 10 để biểu diễn giá trị thứ hai.


<i>c-Hệ đếm bát phân</i>


</div>
<span class='text_page_counter'>(15)</span><div class='page_container' data-page=15>

Phép cộng thêm 1 đơn vị vào một giá trị ta đợc một giá trị là số đứng tiếp
sau. Chẳng hạn 2+1=3. Khi thêm 1 đơn vị vào số tận cùng trong dãy (số 7) ta sử
dụng ký hiệu 10 để biểu diễn giá trị thứ tám.


<i>c-Hệ đếm Hexa</i>


Dùng 16 ký hiệu 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F để biểu diễn
mọi giá trị.


Phép cộng thêm 1 đơn vị vào một giá trị ta đợc một giá trị là số đứng tiếp
sau. Chẳng hạn 9+1=A. Khi thêm 1 đơn vị vào số tận cùng trong dãy (F) ta sử
dụng ký hiệu 10 để biểu diễn giá trị thứ mời sáu.


<i>d-ChuyÓn biểu diễn một giá trị trong hệ thập phân sang biểu diễn trong hệ nhị</i>
<i>phân</i>


<i>Phng phỏp:</i> Chuyn biu din giỏ trị X trong hệ thập phân sang hệ nhị phân.
Lặp lại việc chia số X cho 2 cho đến khi kết quả bằng 0.


Qua mỗi phép chia ta lấy số d của phép chia đó.


Viết kết quả số d theo thứ tự ngợc lại của khi chia ta đợc một biểu diễn
của X trong hệ nhị phân.


<i>VÝ dô:</i> Chuyển biểu diễn của giá trị 29 trong hệ thập phân sang hệ nhị phân.


29 div 2 = 14 d 1


14 div 2 = 7 d 0
7 div 2 = 3 d 1
3 div 2 = 1 d 1


1 div 2 = 0 d 1 (dõng)


VËy, biĨu diƠn cđa giá trị 29 trong hệ nhị phân là: 11101


<i>e-Chuyển biểu diễn một giá trị trong hệ thập phân sang biểu diễn trong hệ nhị</i>
<i>phân.</i>


<i>Phơng pháp:</i>


d hiu phơng pháp chuyển đổi, ta bắt đầu từ biểu diễn một giá trị cụ
thể trong hệ thập phân nh sau: Chẳng hạn một giá trị 308 trong hệ thập phân có
thể đợc viết là: 308 = 3*100 + 0*10 + 8 = 3*102<sub> + 0*10</sub>1<sub> + 8*10</sub>0<sub>.</sub>


Vậy với biểu diễn của giá trị 29 trong hệ nhị phân là 11101 có thể đợc viết
là: 11101 = 1*24<sub> + 1*2</sub>3<sub> + 1*2</sub>2<sub> + 0*2</sub>1<sub> + 1*2</sub>0<sub>. Tính tổng ta thu đợc giá trị là 29.</sub>


<i>Chó ý:</i>


Hình thức chuyển đổi biểu diễn một giá trị giữa các hệ đếm khác cũng
hoàn toàn tơng tự nh trong hai hệ đếm đã trình bày trên.


Ngồi ra, một cách khác, để cho dễ hiểu và dễ thực hiện, ta có thể sử dụng
hệ đếm thập phân làm trung gian trong các phép chuyển đổi.



Chẳng hạn: Để chuyển biểu diễn một giá trị trong hệ bát phân sang hệ nhị
phân, ta chuyển biểu diễn giá tri đó sang hệ thập phân, lấy kết quả trong hệ nhị
phân chuyển tiếp sang hệ bát phân. Minh ha bng s


Bát phân Thập phân Nhị phân
Bát phân Thập phân Nhị phân


<i><b>2-Một số bài toán liªn quan</b></i>


Bài 1: Nhập một số X trong hệ thập phân (1<=X<=2148473647). In ra màn hình
giá trị số đó trong h nh phõn.


<i>Chơng trình:</i>


<b>var i,a,d:word; du:byte;</b>
<b> b:array[1..32000] of byte;</b>
<b>procedure xuli;</b>


<b>begin</b>


</div>
<span class='text_page_counter'>(16)</span><div class='page_container' data-page=16>

<b> d:=0;</b>


<b> while a>0 do</b>
<b> begin</b>


<b> d:=d+1; du:=a mod 2;</b>
<b> b[d]:=du; a:=a div 2;</b>
<b> end;</b>


<b> for i:=d downto 1 do write(b[i]);</b>


<b>end;</b>


<b>begin</b>


<b>xuli;writeln;readln;</b>
<b>end.</b>


Bài 2: Nhập một số X trong hệ nhị phân. In ra màn hình giá trị số đó trong h
thp phõn.


<i>Chơng trình:</i>


<b>var c:string[50]; s1:longint;</b>
<b>function mu(x:byte):longint;</b>


<b> begin</b>


<b> if x=0 then mu:=1 else mu:=mu(x-1)*2;</b>
<b> end;</b>


<b>procedure xuly;</b>


<b>var x,i:byte;ml:integer;</b>
<b>Begin</b>


<b> write('Nhap mot so nhi phan ');</b>
<b> readln(c);</b>


<b> for i:=1 to length(c) do</b>
<b> begin</b>



<b> val(c[i],x,ml);</b>


<b> s1:=s1+mu(length(c)-i)*x;</b>
<b> end;</b>


<b> writeln('Bieu dien thap phan cua ',c,' la ',s1);</b>
<b>end;</b>


<b>begin xuly;readln; </b>
<b>end.</b>


<b>IV-USCLN, BSCNN</b>


<i><b>1-Mét sè kh¸i niƯm liªn quan</b></i>


Để cho dễ hiểu, ta định nghĩa:


+ Số x đợc gọi là ớc số của số a nếu a chia hết cho x. Khi đó a đợc gọilà
bội số của x. Nh vậy a là ớc số của a và a cũng là bội số của a.


+ Sè x lµ USC cđa a vµ b nÕu a chia hÕt cho x vµ b chia hÕt cho x.


+ Số x đợc gọi là USCLN của a và b nếu x là số lớn nhất trong tất cả các
USC của a và b.


+ Sè x lµ BSC cđa a vµ b nÕu x chia hÕt cho a vµ x chia hÕt cho b.


+ Số x đợc gọi là BSCNN của a và b nếu x là số bé nhất trong tất cả các
BSC của a và b.



<i><b>2-Một số bài tập liên quan n USCLN v BSCNN</b></i>


<i>Bài 1:</i> Viết chơng trình nhập vào hai số nguyên dơng X và Y (1<=X,Y<=32767).
In ra màn hình ớc số chung lớn nhất của chúng.


</div>
<span class='text_page_counter'>(17)</span><div class='page_container' data-page=17>

Nếu sử dụng phơng pháp phân tích số đã cho thành thừa số ngun tố thì
bài tốn này khá phức tạp, ở đây xin trình bày một phơng pháp khác. Để hiểu
ph-ơng pháp này, ta bắt đầu bằng ví dụ tìm USCLN của hai số cụ thể 25 và 15.


a b


25 15


10 (=25-15) 15


10 5 (=15-10)


5 5 (Dõng)


Qua ví dụ trên ta khái quát đợc cách giải quyết bài tốn: tìm USCLN của
hai số a và b nh sau:


Lặp lại việc lấy a-b (nếu a>b) hoặc b-a (b>a) cho đến khi a=b.
Khi đó a là USCLN của hai giá trị a và b ban đầu.


<i>ThuËt to¸n:</i>


Bíc 1: NhËp a b



Bíc 2: NÕu a<>b thì lặp


Nếu a>b thì a:=a-b;
Nếu b>a thì b:=b-a;
Bớc 3: Trả lời: xuat(a);


<i>Chơng trình</i>


<b>var x,y:longint;</b>
<b>procedure nhap;</b>
<b>begin</b>


<b> writeln('Nhap vao hai so nguyen duong ');</b>
<b> readln(x,y);</b>


<b>end;</b>


<b>function ucln(a,b:longint):longint;</b>
<b>begin</b>


<b> while a<>b do</b>
<b> begin</b>


<b> if a>b then a:=a-b else b:=b-a;</b>
<b> end;</b>


<b> ucln:=a;</b>
<b>end;</b>


<b>BEGIN</b>



<b>nhap; writeln(ucln(x,y));</b>
<b>readln;</b>


<b>end.</b>


<i>NhËn xÐt:</i>


-Khi a là một số rất lớn (chẳng hạn 2147483647) và b là một số tự nhiên
rất nhỏ (chẳng hạn 1) thì thuật tốn trên sẽ chạy rất chậm, vì mỗi lần lặp chỉ trừ
đi c mt n v.


-Để cải tiến, ta thay phép trừ bằng phép lấy số d
<i>Thuật toán cải tiến:</i>


Bớc 1: Nhập a b


Bớc 2: Nếu a<>b thì lặp


Nếu a>b th× a:=a mod b;
NÕu b>a th× b:=b mod a;


Bíc 3: Trả lời: nếu a>0 thì xuat(a) ngợc lại xuat(b);
<i>VÝ dơ:</i> T×m USCLN cđa hai sè cơ thĨ 35 vµ 15.


a b


</div>
<span class='text_page_counter'>(18)</span><div class='page_container' data-page=18>

5 (=35 mod 15) 15


5 0 (=15 mod 5) (dừng)



<i>Chơng trình c¶i tiÕn:</i>


<b>var x,y:longint;</b>


<b>function ucln(x,y:longint):longint;</b>
<b>var sodu:longint;</b>


<b>begin</b>


<b> while y<>0 do</b>
<b> begin</b>


<b> sodu:=x mod y;</b>
<b> x:=y; </b>


<b> y:=sodu;</b>
<b> end;</b>
<b> ucln:=x</b>
<b>end;</b>


<b>procedure nhap;</b>
<b>begin</b>


<b> writeln('Nhap hai so nguyen duong ');</b>
<b> readln(x,y);</b>


<b>end;</b>
<b>begin</b>



<b>nhap; writeln(ucln(x,y));</b>
<b>readln;</b>


<b>end.</b>


<i>Bài 2:</i> Cho một tệp văn bản B2.INP có cấu trúc
Dòng 1: Ghi số nguyên dơng N (1<=N<=100).
Dòng 2: Ghi N số nguyên dơng ai (1<=ai<=32767)


Yêu cầu: In ra màn hình ớc số chung lớn nhất của N số trong tệp.
<i>Phơng pháp:</i>


Thc ra õy ch l một sự mở rộng của bài tốn tìm USCLN của hai số a b
nh đã đợc trình bày ở trên.


Tuy nhiên trong bài tốn này có hai điểm khác: Thứ nhất, tìm USCLN của
một dãy số. Thứ hai, dữ liệu vào đợc cho trong tệp.


Việc đọc dữ liệu từ tệp xin khụng trỡnh by õy.


Để giải quyÕt t×m USCLN cña mét d·y sè, ta bắt đầu b»ng viƯc t×m
USCLN cđa ba số a b c.


Giả sử x là USCLN cđa a vµ b, ta viÕt x=USCLN(a,b).


Khi đó, để tìm USCLN của a b c ta chỉ cần tìm USCLN của x và c.
y=USCLN(x,c)


Vậy, để tìm USCLN của một dãy số a[], ta thực hiện:



+ Tìm USCLN của a[1] và a[2]: x=USCLN(a[1],a[2])
+ Duyệt từ 3 đến N: tính x=USCLN(x,a[i]);


<i>Chơng trình</i>


<b>const fi='b2.inp';</b>
<b>var f:text;</b>


<b> uc,n:longint;</b>


<b>function ucnn(x,y:longint):longint;</b>
<b>var sodu:longint;</b>


<b> begin</b>


</div>
<span class='text_page_counter'>(19)</span><div class='page_container' data-page=19>

<b> begin</b>


<b> sodu:=x mod y; </b>
<b>x:=y; </b>


<b>y:=sodu;</b>
<b> end;</b>


<b> ucnn:=x;</b>
<b> end;</b>


<b>procedure nhap;</b>
<b>var i,u,v:longint;</b>
<b>begin</b>



<b> assign(f,fi); reset(f);</b>
<b> readln(f,n);</b>


<b> read(f,u);read(f,v);</b>
<b> uc:=ucnn(u,v);</b>


<b> for i:=3 to n do</b>
<b> begin</b>


<b> </b> <b>read(f,v); </b>
<b>uc:=ucnn(uc,v);</b>
<b> end;</b>


<b> close(f);</b>
<b> end;</b>


<b>begin</b>


<b>nhap;writeln(uc);readln;</b>
<b>end.</b>


<i>Bài 3:</i> Viết chơng trình nhập vào hai số nguyên dơng X và Y (1<=X,Y<=32767).
Hãy kiểm tra xem hai số đó có phải là hai số nguyên tố cùng nhau hay không?
<i>Phơng pháp:</i>


Để thuận tiện trong việc giải quyết bài toán, ta nhắc lại khái niệm về hai
số nguyên tố cùng nhau: Hai số nguyên dơng a và b đợc gọi là nguyên tố cùng
nhau nếu ớc số chung lớn nhất của chúng bằng 1.


Nh vậy, để giải quyết bài này trớc hết ta phải tìm USCLN của hai số a và


b. Sau đó trả lời dựa vào kết quả tìm đợc: Nếu USCLN=1 thì hai số đó là nguyên
tố cùng nhau, ngợc lại ta trả lời hai số đó khơng phải ngun tố cùng nhau.


<i>Ph¸t triĨn:</i>


Ta cũng có thể đa thêm khái niệm: Dãy N số nguyên tố cùng nhau nh sau:
Một dãy gồm N số đợc gọi là nguyên tố cùng nhau nếu USCLN của tất c cỏc s
trong dóy bng 1.


<i>Yêu cầu:</i> Cho một dÃy gåm N sè nguyªn. H·y xÐt xem d·y sè cã phải là DÃy N
số nguyên tố cùng nhau hay không?


<i>Bài 4:</i> Viết chơng trình nhập vào hai số nguyên dơng X và Y (1<=X,Y<=32767).
In ra màn hình bội số chung nhỏ nhất của chúng.


<i>Phơng pháp:</i>


Để giải quyết bài toán này, ta phải sử dụng một kết quả của toán học. Đó
là: BSCNN(a,b) = a*b/USCLN(a,b). Chẳng hạn BSCNN(15,25)=15*25/5=75


Vy, tớnh c BSCNN của hai số nguyên dơng a và b, ta chỉ cần tìm
đ-ợc USCLN của hai số đó. Dựa vào phân tích và chơng trình của bài 1, ta gii
quyt c bi ny.


<b>V-Hình học phẳng</b>


</div>
<span class='text_page_counter'>(20)</span><div class='page_container' data-page=20>

Để thuận lợi cho việc giải quyết một số bài toán trong phần tiếp theo, ta đa
ra một số khái niệm cơ së:


-Hình tạo bởi ba đoạn thẳng nối ba điểm khơng thẳng hàng đợc gọi là hình


tam giác.


-Chu vi tam giác là tổng độ dài ba cạnh của một tam giác.


-Diện tích của tam giác là phần mặt phẳng bên trong đợc giới hạn bởi ba
cạnh của tam giác.


-Hình tạo bởi n đoạn thẳng nối n điểm (n>3) đợc gọi là hình đa giác
(khơng có ba điểm nào thẳng hàng).


-Hình đa giác đợc gọi là đa giác lồi nếu ta đi theo cạnh của đa giác thì mọi
điểm thuộc đa giác ln nằm về một phía.


<i><b>2-Mét sè bµi tËp liªn quan</b></i>


<i>Bài 1:</i> Nhập 3 số a, b, c bất kỳ. Hãy kiểm tra xem ba số đó có phải là độ dài ba
cạnh của một tam giác hay khơng? Thơng báo lên màn hình “Phải” hoặc “Khơng
phải”.


<i>Ph©n tÝch:</i>


Thật đơn giản, ta thấy rằng điều kiện để 3 số là độ dài ba cạnh của một
tam giác khi 3 số đó phải là các số dơng và tổng độ dài hai cạnh ln lớn hơn độ
dài cạnh cịn lại.


<i>Ph¬ng ph¸p:</i>


Chỉ cần kiểm tra 6 điều kiện thỏa mãn đồng thời.
a>0 và b>0 và c>0 và a+b>c và a+c>b và b+c>a
<i>Chơng trình:</i>



<b>var a,b,c:real;</b>
<b>begin</b>


<b>write('Hay nhap vao ba so '); readln(a,b,c);</b>


<b>if (a>0)and(b>0)and(c>0)and(a+b>c)and(c+b>a)and(a+c>b) then</b>
<b> writeln('Day la do dai ba canh cua mot tam giac ')</b>


<b>else writeln('Day khong la do dai ba canh cua mot tg');</b>
<b>readln;</b>


<b>end.</b>


<i>Bài 2:</i> Nhập 3 số a, b, c bất kỳ. Hãy kiểm tra xem ba số đó có phải là độ dài ba
cạnh của một tam giác hay khơng? Nếu phải thì tính chu vi và diện tích của tam
giác đó.


<i>Ph©n tÝch: </i>


Tơng tự nh bài 1 ta phải xét xem ba số đó có phải là độ dài ba cạnh của
một tam giác.


Nếu đúng là độ dài ba cạnh của một tam giác, ta thực hiện hai nhiệm vụ:
tính chu vi và tính diện tích.


Tht to¸n:


Bíc 1: NhËp ba sè a b c.



Bớc 2: Nếu ba số là độ dài ba cạnh tam giác:
Tính chi vi CV


TÝnh diƯn tÝch DT
Xt(CV,DT)


Bớc 3: Nếu ba số không phải là độ dài ba cạnh của tam giác:
Xuất(Khong phai do dai ba canh);


<i>Bài 3:</i> Trên mặt phẳng, cho N điểm theo thứ tự là N đỉnh của một đa giác lồi.
Viết chơng trình tính diện tích của đa giác.


</div>
<span class='text_page_counter'>(21)</span><div class='page_container' data-page=21>

<i>N dòng tiếp theo:</i> Mỗi dịng ghi hai số x y là hồnh độ và tung độ của một đỉnh
của đa giác. (-30000 <= x, y <=30000). Hai số ghi cách nhau bởi dấu cách.
<i>Dữ liệu ra:</i> Ghi ra file văn bản DAGIAC.OUT, theo cấu trúc nh sau:


<i>Dịng 1:</i> Ghi diện tích tính đợc.
<i>Phân tớch: </i>


Để dễ hiểu ta giả sử phải tính diện tích đa giác nh trên hình vẽ:
y2


y1


y3


x1 x2 x3


SABC = SADEB + SBEFC - SADFC



= (y2+y1)*(x2-x1)/2 + (y3+y2)*(x3-x2)/2 - (y1+y3)*(x1-x3)/2


= (y2+y1)*(x2-x1)/2 + (y3+y2)*(x3-x2)/2 + (y3+y1)*(x3-x1)/2


Tơng tự ta cũng có thể lập cơng thức tính diện tích cho đa giác bất kỳ.
Để thuận tiện khi lập trình ta xem nh 1 l nh n+1


<i>Thuật toán:</i>


Bớc 1: Đọc dữ liệu trong file vào 2 mảng một chiều x[] và y[]
Đặt x[n+1]:=x[1]; y[n+1]:=y[1]; S:=0;


Bớc 2: Đối với mỗi đỉnh i ta tính tổng S:=S+(y[i]+y[i-1])*(x[i]-x[i-1])/2;
Bớc 3: Trả lời: xuat(abs(S));


<i>Chú ý:</i> Khi đỉnh B của ta giác ABC ở trên quay xuống phía dới thì diện tích ta
tính đợc theo cơng thức trên sẽ là một số âm. Vì vậy khi trả lời kết quả ta phải
lấy giá trị tuyệt đối của nú.


<i>Chơng trình: </i>


<b>const fi='dagiac.inp';</b>
<b> fo='dagiac.out';</b>
<b> maxn=1000;</b>


<b>type mmc=array[1..maxn] of integer;</b>
<b>var a,b:mmc; </b>


<b>n:word; </b>
<b>f:text; </b>


<b>s:real;</b>
<b>procedure nhap;</b>
<b>var i:integer;</b>
<b> begin</b>


<b> </b> <b>assign(f,fi); </b>
<b>reset(f);</b>


<b> </b> <b>readln(f,n);</b>


<b> </b> <b>for i:=1 to n do readln(f,a[i],b[i]);</b>
<b> </b> <b>close(f);</b>


<b> end;</b>


<b>procedure xuly;</b>
<b>var i:integer;</b>
<b> begin</b>


<b> a[n+1]:=a[1]; b[n+1]:=b[1];</b>
<b> s:=0;</b>


<b> for i:=2 to n+1 do</b>


B
A


C


</div>
<span class='text_page_counter'>(22)</span><div class='page_container' data-page=22>

<b> begin</b>



<b> s:=s+(b[i]+b[i-1])*(a[i]-a[i-1])/2;</b>
<b> end;</b>


<b> end;</b>


<b>procedure xuat;</b>
<b> begin</b>


<b> assign(f,fo); rewrite(f);</b>
<b> write(f,abs(s):0:0);</b>


<b> close(f);</b>
<b> end;</b>


<b>begin</b>


<b>nhap;xuly;xuat;</b>
<b>end.</b>


<b>C - Một số bài tập cơ bản.</b>
<i><b>1-Số học</b></i>


<i><b>Bi 1:</b></i> Viết chơng trình nhập ba số bất kỳ. In ra màn hình số lớn nhất và số nhỏ
nhất trong ba s ú.


<i><b>Bài 2:</b></i>Viết chơng trình tính N! (1<=N<=12)


<i><b>Bài 3:</b></i> Viết chơng trình giải bài toán Gà-Chó



Vừa gà, vừa chó. Bó lại cho tròn. Ba mơi sáu con. Một trăm chân chẵn.
Hỏi có bao nhiêu con gà, bao nhiêu con chó?


<i><b>Bài 4:</b></i> Viết chơng trình giải bài toán Trâu-Cỏ


Trm trõu trăm cỏ. Trâu đứng ăn năm. Trâu nằm ăn ba. Trâu già ba con một bó.
Hỏi có bao nhiêu con trâu mỗi loại?


<i><b>Bài 5:</b></i> Ngời ta định nghĩa tam giác Pascal bậc 6 nh sau:
1


1 1


1 2 1


1 3 3 1


1 4 6 4 1


1 5 10 10 5 1


1 6 15 20 15 6 1


H·y lËp tr×nh in ra màn hình tam giác Pascal bậc 20


<i><b>Bài 6:</b></i> Viết chơng trình tính an<sub>. Với a và n là các số nguyên (1<=a,n<=10).</sub>
<i><b>Bài 7:</b></i> Viết chơng trình in ra bảng cửu chơng 1->10


<i><b>Bài 8: </b></i>Viết chơng trình tính tổng của hai sè cã 300 ch÷ sè.



<i><b>Bài 9:</b></i> Ngời ta viết các số tự nhiên liên tục sát nhau đợc một dãy số vơ hạn S.
Viết chơng trình nhập một số ngun dơng N. In ra màn hình chữ số thứ N trong
dóy s vụ hn S núi trờn.


<i><b>2-Xử lý văn bản</b></i>


<i><b>Bài 1:</b></i> Viết chơng trình nhập một xâu ký tự. In ra màn hình mỗi ký tự trên một
dòng.


<i><b>Bài 2:</b></i> Viết chơng trình nhập một xâu ký tự. In ra màn hình mỗi từ trên một dòng
(từ là một nhóm ký tự không có dấu cách)


<i><b>Bài 3:</b></i> Viết chơng trình nhập một xâu ký tự. Đếm số từ có trong xâu.


<i><b>Bài 4:</b></i> Viết chơng trình nhập một xâu ký tự. In ra màn hình từ dài nhất trong
xâu.


<i><b>Bi 5: </b></i>Viết chơng trình nhập một xâu ký tự. In ra màn hình dạng in hoa của xâu
ký tự đó.


</div>
<span class='text_page_counter'>(23)</span><div class='page_container' data-page=23>

<i><b>Bài 7:</b></i> Viết chơng trình nhập vào một số ngun dơng N. In ra màn hình dịng
chữ biểu diễn lời đọc của số đó


<i><b>Bài 8:</b></i> Viết chơng trình nhập một xâu ký tự. Đếm số lần xuất hiện của mỗi ký tự
trong xâu đó.


<i><b>Bài 9: </b></i>Một xâu đợc gọi là đối xứng nếu các ký tự giống nhau đối xứng qua điểm
giữa của xâu.


Viết chơng trình nhập một xâu. In ra màn hình thơng báo “xâu đối xứng” hoc


xõu khụng i xng


<i><b>3-DÃy số</b></i>


<i><b>Bài 1:</b></i> Viết chơng trình tạo ra mét d·y sè gåm N (1<=N<=100) phÇn tư cã giá trị
ngầu nhiên thuộc [1..32000]


<i>Dữ liệu ra:</i> Ghi ra file RAN.OUT, cã cÊu tróc nh sau:
<i>Dßng 1:</i> Ghi sè N, là số lợng phần tử của dÃy


<i>Dũng 2: </i>Ghi N số ngẫu nhiên tìm đợc. Các số ghi cách nhau bi du cỏch.


<i><b>Bài 2:</b></i> Viết chơng trình tìm giá trị lớn nhất của dÃy số.
<i>Dữ liệu vào:</i> Cho trong file LN.INP, cã cÊu tróc nh sau:
<i>Dßng 1:</i> Ghi sè N, là số lợng phần tử của dÃy


<i>Dòng 2: </i>Ghi N số nguyên ai là giá trị của N phần tư thc d·y. C¸c sè ghi c¸ch


nhau bëi dÊu c¸ch.


<i>Dữ liệu ra:</i> Ghi ra file văn bản LN.OUT, theo cấu trúc:
<i>Dịng 1:</i> Ghi số lớn nhất tìm đợc


<i><b>Bài 3:</b></i> Viết chơng trình đếm giá trị lớn nhất của dãy số.
<i>Dữ liệu vào:</i> Cho trong file DLN.INP, có cấu trúc nh sau:
<i>Dòng 1:</i> Ghi số N, là số lợng phần tử ca dóy


<i>Dòng 2: </i>Ghi N số nguyên ai là giá trị của N phần tử thuộc dÃy. Các số ghi c¸ch


nhau bëi dÊu c¸ch.



<i>Dữ liệu ra:</i> Ghi ra file văn bản DLN.OUT, theo cấu trúc:
<i>Dòng 1:</i> Ghi số lợng giá tr ln nht tỡm c.


<i><b>Bài 4:</b></i> Viết chơng trình in ra vị trí của giá trị lớn nhất của dÃy số.
<i>Dữ liệu vào:</i> Cho trong file VTLN.INP, có cấu trúc nh sau:


<i>Dòng 1:</i> Ghi số N, là số lợng phần tử của dÃy


<i>Dòng 2: </i>Ghi N số nguyên ai là giá trị của N phần tử thuộc dÃy. Các số ghi c¸ch


nhau bëi dÊu c¸ch.


<i>Dữ liệu ra:</i> Ghi ra file văn bản VTLN.OUT, theo cấu trúc:
<i>Dòng 1:</i> Ghi số M là số lợng giá trị lớn nhất tìm đợc.


<i>Dßng 2: </i>Ghi M số nguyên ik là chỉ số của M phần tử có giá trị lớn nhất thuộc


dÃy. Các số ghi cách nhau bởi dấu cách.


<i><b>Bài 5:</b></i> Viết chơng trình tìm giá trị lớn thứ nhì của dÃy số.
<i>Dữ liệu vào:</i> Cho trong file LN2.INP, có cấu trúc nh sau:
<i>Dòng 1:</i> Ghi số N, là số lợng phần tử của dÃy


<i>Dòng 2: </i>Ghi N số nguyên ai là giá trị của N phần tử thuộc dÃy. Các số ghi c¸ch


nhau bëi dÊu c¸ch.


<i>Dữ liệu ra:</i> Ghi ra file văn bản LN2.OUT, theo cấu trúc:
<i>Dòng 1:</i> Ghi giá trị lớn nhì tìm đợc



<i><b>Bài 6:</b></i> Sắp xếp dãy số theo thứ tự giảm dần, trong đó số lợng các số ging nhau
khụng quỏ 255.


<i>Dữ liệu vào:</i> Cho trong file văn bản SAPDAY.INP, có cấu trúc:
<i>Dòng 1:</i> Ghi số N, là số lợng phần tử của dÃy


<i>Dòng 2: </i>Ghi N số nguyên ai là giá trị của N phần tử thuộc d·y. C¸c sè ghi c¸ch


nhau bëi dÊu c¸ch.


</div>
<span class='text_page_counter'>(24)</span><div class='page_container' data-page=24>

<i>Dòng 1: </i>Ghi N số nguyên ai là giá trị của N phần tử thuộc dãy sau khi đã sắp


xÕp. C¸c sè ghi c¸ch nhau bëi dÊu c¸ch.


<b>D-Mét số bài tập tuyển chọn</b>


<b>Câu 1: GAPGIAY.PAS</b>


Cú mt tờ giấy dày a (mm) (0.001<a<5). Hỏi phải gấp đơi tờ giấy ít nhất
bao nhiêu lần để đợc độ dày lớn hơn b (cm) (0.001<b<10). Kết quả xuất ra màn
hình.


VÝ dơ: NhËp a=1 b=1. Xuất: Số lần phải gấp ít nhất là: 4
Chơng trình gỵi ý:


<b>var a,b:real;</b>
<b> d:word;</b>
<b>begin</b>



<b>write('Hay nhap vao do dai ban dau (mm) a=');readln(a);</b>
<b>write('Hay nhap vao do dai can co (cm) b=');readln(b);</b>
<b>b:=10*b;</b>


<b>d:=0;</b>


<b>while a<b do</b>
<b> begin</b>


<b> a:=a*2; d:=d+1;</b>
<b> end;</b>


<b>writeln('Sau it nhat la ',d,' lan gap ');</b>
<b>readln;</b>


<b>end.</b>


Test gợi ý:


a b Số lần gấp


0.1 1 7


1 5 6


20 1 0


1 0.2 1


<b>C©u 2: USCLN.PAS</b>



¦íc sè chung lín nhÊt cđa d·y gåm N số nguyên dơng A1,A2,,An là
một số nguyên dơng U lớn nhất sao cho với mọi giá trị của i (i=1..N) th× Ai chia
hÕt cho U.


Cho mét file văn bản có tên USCLN.INP và có cấu trúc nh sau:
Dòng 1: Chứa số N (N nguyên dơng, N<51).


Dòng 2: Chứa N số Ai (Ai nguyên dơng, 0<Ai<65536), mỗi số ghi cách nhau ít
nhất một dấu cách trống.


Hóy viết chơng trình đọc N số từ file trên và tìm ớc số chung lớn nhất của
dãy N số đó. u cầu chơng trình chạy khơng q 2 giây.


Kết quả xuất ra file có tên USCLN.OUT có cấu trúc:
Dịng 1: Chứa số U là ớc số chung lớn nhất tìm đợc.


VÝ dơ:


USCLN.INP USCLN.OUT


6 5


100 25 50 30
Chơng trình gỵi ý:


<b>const fi='USCLN.INP ';</b>
<b> fo='USCLN.OUT';</b>


<b>type mmc=array[1..100] of longint;</b>


<b>var a:mmc;</b>


</div>
<span class='text_page_counter'>(25)</span><div class='page_container' data-page=25>

<b>assign(f,fi);</b>
<b>reset(f);</b>
<b>readln(f,n);</b>


<b>for i:=1 to n do read(f,a[i]);</b>
<b>close(f);</b>


<b>end;</b>


<b>function uc(x,y:longint):longint;</b>
<b>begin</b>


<b>while x<>y do</b>
<b> begin</b>


<b> if x>y then x:=x-y else y:=y-x;</b>
<b> end;</b>


<b>uc:=x;</b>
<b>end;</b>


<b>procedure xuly;</b>
<b>var i:byte;</b>


<b> u,uhs:longint;</b>
<b>begin</b>


<b>u:=uc(a[1],a[2]);</b>



<b>for i:=3 to n do u:=uc(u,a[i]);</b>
<b>writeln('UCLN la' ,u);</b>


<b>assign(f,fo);</b>
<b>reset(f);</b>
<b>readln(f,uhs);</b>
<b>close(f);</b>


<b>if u=uhs then write('1 diem') else write('0 diem');</b>
<b>readln;</b>


<b>end;</b>
<b>begin</b>
<b>doc;</b>
<b>xuly;</b>
<b>end.</b>


<b>C©u 3: TANSO.PAS</b>


Ngêi ta nãi tÇn sè cđa mét sè A trong mét d·y sè A1, A2, …,An lµ sè lÇn
xt hiƯn cđa sè A trong d·y A1,A2,…,An.


VÝ dơ: Cho d·y sè 2 3 4 5 1 3 3 4 3
TÇn sè cđa sè 2 là 1. Tần số của số 3 là 4.


Cho một file văn bản có tên TANSO.INP và cã cÊu tróc nh sau:
Dßng 1: Chøa sè nguyên N dơng (0<N<=10000)


N dòng tiếp theo: mỗi dòng chứa một số nguyên Ai (0<Ai<101), các số ghi c¸ch


nhau Ýt nhÊt mét dÊu c¸ch trèng.


Hãy viết chơng trình đọc file trên và tìm tần số xuất hiện của các số trong
N số đã cho. Yêu cầu chơng trình chạy khơng q 2 giây.


Kết quả xuất ra file văn bản TANSO.OUT gồm nhiều dòng. Mỗi dòng
chứa 2 số Ai và Ki ghi cách nhau ít nhất một dấu cách trống. Trong đó Ai là số
thuộc dãy, Ki là tần số của số Ai. Ai đợc xếp tăng dần từ đầu đến cuối file.
Ví dụ:


TANSO.INP TANSO.OUT


9 1 1


2 3 4 6 1 3 3 4 3 2 1


6 4


6 2


6 1


Chơng trình gọi ý:


</div>
<span class='text_page_counter'>(26)</span><div class='page_container' data-page=26>

<b>const fi='Tanso.inp';</b>
<b> fo='Tanso.out';</b>


<b>type mmc=array[0..100] of word;</b>
<b>var a:mmc;</b>



<b> f:text;</b>
<b> n,d:word;</b>
<b>procedure doc;</b>
<b>var i,x:word;</b>
<b>begin</b>


<b>for i:=0 to 100 do a[i]:=0;</b>
<b>assign(f,fi);</b>


<b>reset(f);</b>
<b>readln(f,n);</b>


<b>for i:=1 to n do begin read(f,x); a[x]:=a[x]+1;end;</b>
<b>close(f);</b>


<b>d:=0;</b>


<b>for i:=1 to 100 do</b>


<b> if a[i]>0 then d:=d+1;</b>
<b>{assign(f,fo);</b>


<b>rewrite(f);</b>


<b>for i:=1 to 100 do</b>


<b> if a[i]>0 then writeln(f,i,' ',a[i]);</b>
<b>close(f);}</b>


<b>end;</b>



<b>procedure tt;</b>
<b>var i:word;</b>
<b>begin</b>


<b>randomize;</b>
<b>n:=10000;</b>
<b>assign(f,fi);</b>
<b>rewrite(f);</b>
<b>writeln(f,n);</b>


<b>for i:=1 to n do write(f,random(99)+1,' ');</b>
<b>close(f);</b>


<b>end;</b>


<b>procedure cham;</b>
<b>var i,diem:word;</b>
<b> ahs,khs:mmc;</b>
<b>begin</b>


<b>assign(f,fo);</b>
<b>reset(f);</b>


<b>for i:=1 to d do read(f,ahs[i],khs[i]);</b>
<b>close(f);</b>


<b>diem:=0;</b>


<b>for i:=1 to d do if (a[ahs[i]]<>khs[i]) then diem:=diem+1;</b>


<b>if diem=0 then writeln('1 diem');</b>


<b>if diem=1 then writeln('0.5 diem');</b>
<b>if diem>1 then writeln('0 diem');</b>
<b>end;</b>


<b>begin</b>
<b>doc;</b>
<b>cham;</b>
<b>readln;</b>
<b>end.</b>


<b>C©u 4: </b> <b>NT.PAS</b>


</div>
<span class='text_page_counter'>(27)</span><div class='page_container' data-page=27>

Dịng 1: Chứa số N, là số lợng số nguyên tố tìm đợc.


Dịng 2: Ghi các số ngun tố tìm đợc, mỗi số ghi cách nhau ít nhất một dấu
cách trống.


Ch¬ng trình gợi ý:


<b>{$R+}</b>


<b>const n=60000;</b>


<b>type mmc=array[1..n] of boolean;</b>
<b>var a:longint;</b>


<b> b:mmc;</b>
<b> f:text;</b>


<b>procedure nt2;</b>


<b>var i,j,x,d,sl:longint;</b>
<b>begin</b>


<b> for i:=1 to n do b[i]:=true;</b>
<b> b[1]:=false;</b>


<b> for i:=2 to n do</b>
<b> begin</b>


<b> if b[i]=true then</b>


<b> for j:=i to (n div i) do b[i*j]:=false;</b>
<b> end;</b>


<b> sl:=0;</b>


<b> for i:=1 to n do</b>


<b> if b[i]=true then sl:=sl+1;</b>
<b>{xuat}</b>


<b>{assign(f,'NT.OUT');</b>
<b>rewrite(f);</b>


<b>for i:=1 to n do if b[i]=true then write(f,i,' ');</b>
<b>close(f);}</b>


<b>{cham}</b>



<b>assign(f,'NT.OUT');</b>
<b>reset(f);</b>


<b>d:=0;</b>


<b>while not seekeof(f) do</b>
<b> begin</b>


<b> read(f,x);</b>


<b> if b[x]=false then d:=d+1;</b>
<b> end;</b>


<b>if d=0 then writeln('2 diem');</b>


<b>if (0<d) and (d<=sl div 2) then write('1 diem ');</b>
<b>if d>sl div 2 then write('0 diem ');</b>


<b>close(f);</b>
<b>end;</b>
<b>begin</b>
<b>nt2;</b>
<b>readln;</b>
<b>end.</b>


<b>Câu 5: </b> <b>TOT.PAS</b>


Có một băng giấy gồm N ô (1<N<30). Một con tốt ở bên trái của băng
giấy. Con tốt có 2 loại bớc đi:



Bớc đi loại 1: từ ô i sang ô i+1.
Bớc đi loại 2: từ ô i sang ô i+2.


Viết chơng trình nhập số N (Số lợng ô của băng giấy) và tìm số cách di
chuyển con tốt từ bên trái sang bên phải của băng giấy. Kết quả xuất ra màn
hình.


</div>
<span class='text_page_counter'>(28)</span><div class='page_container' data-page=28>

VÝ dơ: N= 5 Sè c¸ch di chun con tốt: 13
Chơng trình gợi ý:


<b>type mmc=array[0..31] of longint;</b>
<b>var a:mmc;</b>


<b> i,j,n:byte;</b>
<b>begin</b>


<b>write('Hay nhap so o cua bang giay ');</b>
<b>readln(n);</b>


<b>a[0]:=1;</b>
<b>a[1]:=1;</b>


<b>for i:=2 to n+1 do a[i]:=a[i-1]+a[i-2];</b>
<b>writeln('So cach di chuyen la ',a[n+1]);</b>
<b>readln;</b>


<b>end.</b>


<b>Test gợi ý:</b>



N Số cách di chuyển


10 144


20 17711


30 2178309


29 1346269


<b>Câu 6: TAPCON.PAS</b>


Một tập S gồm N phần tử là A1,A2,...,An, tập S1 gồm M phần tử là
B1,B2,..Bm đợc gọi là “tập con phân biệt” của tập S nếu:


+ Mäi i (i=1..m) th× Bi thuéc tËp S vµ


+ Mäi j, k (j, k=1..m) mµ j<>k th× Bj<>Bk.
VÝ dơ: S={1 2 4 6 2 5 8 2} th×


S1={1 2 4 6 5} lµ mét tËp con ph©n biƯt cđa S


S2={1 2 4 6 2} không phải là một tập con phân biệt của S.
Cho một file văn bản có tên TAPCON.INP và có cấu trúc nh sau:
Dòng 1: chứa số nguyên dơng N(0<n<10001), là số lợng phần tử của tập S


Dòng 2: chứa N số nguyên dơng Ai (0<A[i]<20001). C¸c sè ghi c¸ch nhau Ýt
nhÊt mét dÊu c¸ch trèng.



Viết chơng trình đọc file trên và tìm tập con S1 phân biệt của tập S gồm N
số đó sao cho S1 có số lợng phần tử là nhiều nhất.


KÕt qu¶ xt ra file TAPCON.OUT cã cÊu tróc nh sau:


Dòng 1: Số M, là số lợng các phần tử thuộc tập con phân biệt tìm đợc.


Dịng 2: Gồm M số Bi là giá trị các phần tử của tập con phân biệt tìm đợc. Các
số ghi cách nhau ít nhất một dấu cách trống.


VD:


TAPCON.INP TAPCON.OUT


8 5


1 4 6 1 6 7 4 2 1 4 6 7 2
Chơng trình gợi ý:


<b>{$R+}</b>


<b>const fi='TAPCON.IN1';</b>
<b> fo='TAPCON.OUT';</b>
<b> max=20000;</b>


<b>type mmc=array[1..max] of boolean;</b>
<b>var a,hs:mmc;</b>


<b> n,m,d:longint;</b>
<b> f:text;</b>



<b>procedure tt;</b>
<b>var i:longint;</b>
<b>begin</b>


</div>
<span class='text_page_counter'>(29)</span><div class='page_container' data-page=29>

<b>rewrite(f);</b>
<b>randomize;</b>
<b>n:=5000;</b>
<b>writeln(f,n);</b>


<b>for i:=1 to n do write(f,random(20000)+1,' ');</b>
<b>close(f);</b>


<b>end;</b>


<b>procedure doc;</b>
<b>var i,x:longint;</b>
<b>begin</b>


<b>for i:=1 to max do a[i]:=false;</b>
<b>assign(f,fi);</b>


<b>reset(f);</b>
<b>readln(f,n);</b>
<b>for i:=1 to n do</b>
<b> begin</b>


<b> read(f,x);</b>
<b> a[x]:=true;</b>
<b> end;</b>



<b>close(f);</b>
<b>{xuat ra file}</b>
<b>{assign(f,fo);</b>
<b>rewrite(f);</b>
<b>for i:=1 to n do</b>


<b> if a[i]=true then write(f,i,' ');</b>
<b>close(f);}</b>


<b>{cham}</b>


<b>assign(f,fo);</b>
<b>reset(f);</b>
<b>readln(f,m);</b>
<b>d:=0;</b>


<b>for i:=1 to m do</b>
<b> begin</b>


<b> read(f,x);</b>


<b> if a[x]=false then d:=d+1;</b>
<b> end;</b>


<b>if d=0 then writeln('1 diem')</b>
<b>else writeln('0 diem');</b>
<b>close(f);</b>


<b>readln;</b>


<b>end;</b>
<b>begin</b>
<b>doc;</b>
<b>end.</b>


<b>Câu 7: Hai xâu tơng đơng - XAUTD.PAS</b>


Ngời ta định nghĩa hai xâu tơng đơng nh sau: Xâu A và xâu B đợc gọi là
t-ơng đt-ơng nếu tồn tại một cách sắp xếp các ký tự của xâu A để thu đợc xâu B
hoặc tồn tại một các sắp xếp các ký tự của xâu B để thu đợc xâu A.


Ví dụ: Xâu ABC là tơng đơng với xâu BCA.
Cho hai xâu A và B thỏa mãn các điều kiện sau:


+Có độ dài bằng nhau và đều bằng n 1<=n<=10000.


+Các ký tự xuất hiện trong xâu chỉ gồm các ký tự in hoa từ ‘A’ đến ‘Z’.
Hãy xét xem hai xâu A và B có tơng đơng với nhau hay khơng?


<i>Dữ liệu vào: </i>Cho trong file XAUTD.INP có cấu trúc nh sau:
+Dịng 1: Ghi số n, là độ dài của mỗi xâu.


</div>
<span class='text_page_counter'>(30)</span><div class='page_container' data-page=30>

<i>D÷ liƯu ra:</i> Ghi ra file XAUTD.OUT theo cÊu tróc nh sau:


+Dịng 1: Ghi 1 nếu xâu A tơng đơng với xâu B, ghi 0 nếu xâu A không
t-ng t-ng vi xõu B.


Ví dụ:


XAUTD.INP XAUTD.OUT



3
ABC
BAC


1


4
XNYZ
YNYZ


0


Chơng trình gợi ý:


const fi='xautd.in6';
fo='xautd.ou6';
type mmc=array['A'..'Z'] of word;
var f:text; n:word; m1,m2:mmc;
procedure doc;


var i:word;c:char;
begin


assign(f,fi);reset(f);
readln(f,n);


fillchar(m1,sizeof(m1),0);
for i:=1 to n do



begin


read(f,c);


m1[c]:=m1[c]+1;
end;


readln(f);
for i:=1 to n do
begin


read(f,c);


m2[c]:=m2[c]+1;
end;


close(f);
end;


procedure xl;
var i:char; kq:byte;
begin


kq:=1;


for i:='A' to 'Z' do


if m1[i]<>m2[i] then begin kq:=0; break; end;
assign(f,fo);



rewrite(f);
write(f,kq);
close(f);
end;


begin
doc;
xl;
end.


</div>
<span class='text_page_counter'>(31)</span><div class='page_container' data-page=31>

Trong mặt phẳng, cho n điểm. Hãy xác định xem, nếu đi theo thứ tự của
các điểm đó thì chúng có tạo đợc một đa giác lồi hay khơng? Nếu đợc hãy tính
diện tích của đa giác lồi đó.


<i>D÷ liƯu vào:</i> Đợc cho trong file POLYGON.INP có cấu trúc nh sau:
-Dßng 1: Ghi sè n. (3<=n<=100)


-n dịng tiếp theo: mỗi dòng 2 số ai bi là toạ độ điểm thứ i. Hai số ghi cách nhau


Ýt nhÊt mét dÊu c¸ch. (-2000<=ai ,bi <=2000)


<i>D÷ liƯu ra: </i>Ghi ra file POLYGON.OUT theo cÊu tróc nh sau:


-Dịng 1: Ghi số 0 nếu đi theo thứ tự của n điểm trên sẽ không tạo đợc một đa
giác lồi. Ghi số 1 nếu đi theo thứ tự n điểm trên sẽ tạo đợc một đa giác lồi.


-Dòng 2: Nếu đi theo thứ tự n điểm trên sẽ tạo đợc đa giác lồi thì ghi diện tích
của đa giác đó (tính chính xác đến 2 chữ số thập phân).


VÝ dô:



POLYGON.INP POLYGON.OUT
3


0 0
1 0
0 1


1
0.50


4
0 0
1 0
0 1
-1 -1


0


Ch¬ng trình gợi ý:
const fi='polygon.in6';
fo='polygon.ou6';
maxn=1000;


type mmc=array[1..maxn] of longint;


var a,b:mmc; n:word; dt:real;f:text; loi:boolean;
procedure doc;


var i:word;


begin


assign(f,fi);
reset(f);
readln(f,n);


for i:=1 to n do readln(f,a[i],b[i]);
close(f);


end;


function dientich:real;


var i:word; s:real;t1,t2:longint;
begin


s:=0;


for i:=1 to n do
begin


t1:=(b[i]+b[i+1]);
t2:=(a[i+1]-a[i]);
s:=s+(t1/2)*t2;


end;


dientich:=s;
end;



procedure xuly;


</div>
<span class='text_page_counter'>(32)</span><div class='page_container' data-page=32>

begin


a[n+1]:=a[1];
b[n+1]:=b[1];
a[n+2]:=a[2];


b[n+2]:=b[2];


d1:=0;d2:=0;d0:=0;loi:=false;
for i:=1 to n do


begin


d:=(a[i+1]-a[i])*(b[i+2]-b[i])-(a[i+2]-a[i])*(b[i+1]-b[i]);
if d>0 then inc(d1);


if d<0 then inc(d2);
if d=0 then inc(d0);
end;


if d0<n then


if (d0+d1=n) or (d0+d2=n) then
begin


loi:=true;
dt:=dientich;
end;



end;


procedure xuat;
begin


assign(f,fo);
rewrite(f);
if loi=true then
begin


writeln(f,1);


writeln(f,abs(dt):0:2);
end


else write(f,0);
close(f);


end;
begin


doc;
xuly;
xuat;
end.


<b>C©u 9: D·y A2n DAYA2N.PAS</b>


D·y A2n là một dÃy số thỏa mÃn các tính chất sau:


+ Gåm 2n+1 phÇn tư a0, a1, ... , a2n


+ a0 = a2n = 0


+ ai nguyên, không âm và luôn cã | ai – ai+1| =1 víi mäi i=0..2n-1


VÝ dơ: víi n = 3 ta cã 5 d·y sè:


1) 0 1 0 1 0 1 0
2) 0 1 0 1 2 1 0
3) 0 1 2 1 0 1 0
4) 0 1 2 1 2 1 0
5) 0 1 2 3 2 1 0
Yêu cầu: Cho trớc số n, hÃy tìm số lợng dÃy A2n


Dữ liệu vào: Cho trong file DAYA2N.INP cã cÊu tróc nh sau:
- Dßng 1: Ghi mét sè n (1<=n<=19)


</div>
<span class='text_page_counter'>(33)</span><div class='page_container' data-page=33>

-Dòng 1: Ghi một số S là số lng dóy s A2n tỡm c.
Vớ d:


DAYA2N.INP DAYA2N.OUT


3 5


Chơng trình gỵi ý:


const fi='DAY2N.IN4';
fo='DAY2N.OU4';



type mhc=array[0..60,0..60] of longint;
var f:text;


n:word;
a:mhc;
procedure doc;
begin


assign(f,fi);
reset(f);
readln(f,n);
close(f);
n:=n+1;
end;


procedure xl;
var i,j:word;
begin


for i:=1 to n do a[1,i]:=1;
for i:=2 to n do


for j:=i to n do
if i=j then a[i,j]:=a[i-1,j]
else a[i,j]:=a[i,j-1]+a[i-1,j];
end;


procedure xuat;
var i,j:word;
begin



assign(f,fo);
rewrite(f);


writeln(f, a[n,n]);
close(f);


end;
begin


doc;
xl;
xuat;
end.


<b>Câu 10: Tổng giá trị các phần tử trong một ma trận - SUM.PAS</b>


Cho mt ma trận A gồm M dòng N cột. Dòng đợc đánh số từ 1 đến M từ
trên xuống dới. Cột đợc đánh số từ 1 đến N từ trái qua phải. Mỗi phần tử của ma
trận có giá trị nguyên. Hãy tính tổng giá trị các phần tử có chỉ s dũng chn v
ch s ct l.


<i>Dữ liệu vào:</i> Cho trong file SUM.INP cã cÊu tróc nh sau:


-Dßng 1: Ghi hai giá trị M N, là số dòng và số cét cđa ma trËn, c¸c sè ghi c¸ch
nhau mét dÊu cách. (2<=M, N<=100)


-M dòng tiếp theo: mỗi dòng ghi N số nguyên <i>x</i>, là các giá trị của các phần tử
trên một dòng của ma trận, các số ghi cách nhau mét dÊu c¸ch.



</div>
<span class='text_page_counter'>(34)</span><div class='page_container' data-page=34>

<i>Dữ liệu ra:</i> Ghi ra file SUM.OUT theo cấu trúc nh sau:
-Dòng 1: Ghi một số S, là tổng tìm đợc.


<i><b>VÝ dơ:</b></i>


SUM.INP SUM.OUT


4 5 31


2 4 1 5 7
2 2 8 3 5
1 7 4 8 0
9 6 4 7 3


<b>{$r+}</b>


<b>const fi='Sum.in2';</b>
<b> fo='sum.ou2';</b>
<b> nn=100;mm=100;</b>


<b>type mhci=array[1..mm,1..nn] of integer;</b>
<b>var a:mhci;</b>


<b> m,n:byte;</b>
<b> s:longint;</b>
<b>procedure doc;</b>


<b>var f:text; i,j:byte;</b>
<b>begin</b>



<b>assign(f,fi);reset(f);</b>
<b>readln(f,m,n);</b>


<b>for i:=1 to m do</b>
<b> begin</b>


<b> for j:=1 to n do read(f,a[i,j]);</b>
<b> readln(f);</b>


<b> end;</b>
<b>close(f);</b>
<b>end;</b>


<b>procedure xl;</b>
<b>var i,j:byte;</b>
<b>begin</b>


<b>s:=0;</b>


<b>for i:=1 to m do</b>
<b> begin</b>


<b> for j:=1 to n do</b>


<b> if (i mod 2=0) and (j mod 2=1) then s:=s+a[i,j];</b>
<b> end;</b>


<b>end;</b>


<b>procedure xuat;</b>



<b>var i,j:byte; f:text;</b>
<b>begin</b>


<b>assign(f,fo); rewrite(f);</b>
<b>writeln(f,s);</b>


<b>close(f);</b>
<b>end;</b>
<b>begin</b>
<b>doc;</b>
<b>xl;</b>
<b>xuat;</b>
<b>readln;</b>
<b>end.</b>


</div>
<span class='text_page_counter'>(35)</span><div class='page_container' data-page=35>

<b>SUM.INP</b> <b>SUM.OUT</b>


<b>5 5</b>


<b>2 4 1 5 7</b>
<b>2 2 8 3 5</b>
<b>1 7 4 8 0</b>
<b>9 6 4 7 3</b>
<b>8 5 3 2 7</b>


<b>31</b>


<b>6 5</b>



<b>2 4 1 5 7</b>
<b>2 2 8 3 5</b>
<b>1 7 4 8 0</b>
<b>9 6 4 7 3</b>
<b>8 5 3 2 7</b>
<b>3 -1 -2 -3 -4</b>


<b>28</b>


<b>4 5</b>


<b>4 5 6 7 2</b>
<b>-1 2 3 9 10</b>
<b>4 3 -20 3 6</b>
<b>-19 13 20 -20 2</b>


<b>15</b>


<b>Câu 11: Số nguyên tè </b>–<b> NT.PAS</b>


Tìm tất cả các số tự nhiên X có ba chữ số sao cho khi đảo ngợc trật tự các
chữ số của X ta sẽ thu đợc một số nguyên Y mà X và Y là hai số ngun tố cùng
nhau.


<i>VÝ dơ:</i> X=122 vµ Y= 221


<i>Dữ liệu ra:</i> Ghi ra file NT.OUT theo cấu trúc nh sau:
-Dòng 1: Ghi số nguyên dơng N, là số lợng số X tìm đợc.


-Dịng 2: Ghi N số tìm đợc. Các số ghi cách nhau một dấu cách.



<b>const fo='NT.OUT';</b>
<b> nn=901;</b>


<b>type mmcw=array[0..901] of word;</b>
<b>var n:word; s:mmcw;</b>


<b>function uscln(a,b:word):word;</b>
<b>var r:word;</b>


<b>begin</b>


<b>while b>0 do</b>
<b> begin </b>
<b>r:=a mod b; </b>
<b>a:=b; </b>


<b>b:=r; </b>
<b>end;</b>


<b>uscln:=a;</b>
<b>end;</b>


<b>function dao(x:word):word;</b>
<b>var y:word;</b>


<b>begin</b>
<b> y:=0;</b>


<b> while x>0 do</b>


<b> begin </b>


<b>y:=10*y+(x mod 10); </b>
<b>x:=x div 10; </b>


<b>end;</b>
<b>dao:=y;</b>
<b>end;</b>


</div>
<span class='text_page_counter'>(36)</span><div class='page_container' data-page=36>

<b>var x,d:word;</b>
<b>begin</b>


<b>d:=0;</b>


<b>for x:=100 to 999 do</b>


<b> if uscln(x,dao(x))=1 then</b>
<b> begin </b>


<b>d:=d+1; </b>
<b>s[d]:=x; </b>
<b>end;</b>


<b>tim:=d;</b>
<b>end;</b>


<b>procedure xuat;</b>
<b>var f:text; i:word;</b>
<b>begin</b>



<b>n:=tim;</b>


<b>assign(f,fo);rewrite(f);</b>
<b>writeln(f,n);</b>


<b>for i:=1 to n do write(f,s[i],' ');</b>
<b>close(f);</b>


<b>end;</b>
<b>begin</b>
<b>xuat;</b>
<b>end.</b>


<b>Câu 12: Sắp xếp xâu </b><b> STR.PAS</b>


Cho mt xõu mẫu S gồm N ký tự đợc lấy từ tập các ký tự ‘A’...‘Z’. Với
một cặp số nguyên (i,j) (1<=i,j<=N), ta tạo ra một xâu thứ cấp S’ bằng cách đổi
chỗ phần tử thứ i với phần tử thứ j của xâu mẫu S. Với M cặp số (i,j) ta s thu
-c M xõu th cp.


<i>Yêu cầu:</i> Sắp xếp các xâu thứ cấp tăng dần theo thứ tự từ điển.
<i>Dữ liệu vào:</i> Cho trong file STR.INP có cấu trúc nh sau:
-Dòng 1: Ghi giá trị N, là số ký tự của xâu S (1<=N<=500)
-Dòng 2: Ghi xâu mẫu S.


-Dòng 3: Ghi giá trị M, là số lợng các cặp số (i, j) (1<=M<=500)


-M dũng tip theo: mi dòng ghi một cặp số i j lần lợt là chỉ số của phần tử thứ
i và chỉ số của phần tử thứ j cần đổi chỗ của xâu S. Hai số ghi cách nhau một dấu
cách.



<i>D÷ liƯu ra:</i> Ghi ra file STR.OUT theo cÊu tróc nh sau:


-M dòng: Mỗi dòng ghi một xâu thứ cấp, các dòng đợc sắp tăng dần theo thứ tự
từ điển.


<i><b>VÝ dô:</b></i>


STR.INP STR.OUT


5 ABCDA


ABCDA ABCDA


3 ADCBA


2 4
1 5
3 3


<b>{$r+}</b>


<b>program sap_xau;</b>


<b>const </b> <b>fi='str.in5'; </b>
<b>fo='str.ou5';</b>


</div>
<span class='text_page_counter'>(37)</span><div class='page_container' data-page=37>

<b>var d,s,b,c,tg1:mmcc;</b>
<b> l,r:mmci;</b>



<b> n,m:integer;</b>
<b> f:text;</b>
<b>procedure nhap;</b>
<b>var i,j:integer;</b>
<b>begin</b>


<b> assign(f,fi); reset(f);</b>
<b> readln(f,n);</b>


<b> for i:=1 to n do read(f,s[i]);</b>
<b> readln(f);</b>


<b> readln(f,m);</b>


<b> for i:=1 to m do readln(f,l[i],r[i]);</b>
<b> close(f);</b>


<b>end;</b>


<b>procedure doicho(var x,y:char);</b>
<b>var tg:char;</b>


<b>begin</b>


<b> tg:=x; </b>
<b>x:=y; </b>
<b>y:=tg;</b>
<b>end;</b>


<b>procedure xl;</b>



<b>var i,j,k,tg:integer;</b>
<b>begin</b>


<b> for i:=1 to m-1 do</b>
<b> begin</b>


<b> b:=s;</b>


<b> doicho(b[l[i]],b[r[i]]);</b>
<b> for j:=i+1 to m do</b>


<b> begin</b>
<b> c:=s;</b>


<b> doicho(c[l[j]],c[r[j]]);</b>
<b> for k:=1 to n do</b>


<b> begin</b>


<b> if b[k]>c[k] then</b>
<b> begin</b>


<b> tg:=l[i];l[i]:=l[j];l[j]:=tg;</b>
<b> tg:=r[i];r[i]:=r[j];r[j]:=tg;</b>
<b> tg1:=b;b:=c;c:=tg1;</b>


<b> break;</b>
<b> end;</b>



<b> if b[k]<c[k] then break;</b>
<b> end;</b>


<b> end;</b>
<b> end;</b>


<b> assign(f,fo); rewrite(f);</b>
<b> for i:=1 to m do</b>


<b> begin</b>
<b> d:=s;</b>


<b> doicho(d[l[i]],d[r[i]]);</b>


</div>
<span class='text_page_counter'>(38)</span><div class='page_container' data-page=38>

<b> end;</b>
<b> close(f);</b>
<b>end;</b>


<b>begin</b>
<b> nhap;</b>
<b> xl;</b>
<b>end.</b>


<b>C©u 13: Đếm số từ có trong xâu-WORD.PAS</b>


Ta nh ngha: Từ là một nhóm ký tự bất kỳ mà trong đó khơng chứa dấu
cách. Ví dụ ‘thch’ là một từ.


Cho một xâu S gồm N ký tự đợc lấy từ tập ký tự ‘a’...’z’ và ‘ ’ (dấu cỏch),
(1<=N<=255)



<i>Yêu cầu:</i> Đếm số lợng từ có trong xâu và in ra file mỗi từ trên một dòng.
<i>Dữ liệu vào:</i> Cho trong file WORD.INP cã cÊu tróc nh sau:


-Dßng 1: Ghi x©u S.


<i>Dữ liệu ra:</i> Ghi ra file WORD.OUT theo cấu trúc nh sau:
-Dòng 1: Ghi số K là số lợng từ đếm đợc có trong xâu.
-K dịng tiếp theo, mỗi dịng ghi một từ.


<i><b>VÝ dơ:</b></i>


WORD.INP WORD.OUT


bien hoc khong bo 4
bien
hoc
khong
bo
Chơng trình gợi ý


<b>const fi='word.in5';</b>
<b> fo='word.ou5';</b>
<b>var s:string;</b>


<b> f:text;</b>
<b> d:byte;</b>
<b>procedure doc;</b>
<b>begin</b>



<b>assign(f,fi);</b>
<b>reset(f);</b>
<b>readln(f,s);</b>
<b>close(f);</b>
<b>end;</b>


<b>procedure xl;</b>
<b>var i:byte;</b>
<b>begin</b>


<b>while s[1]=' ' do delete(s,1,1);</b>


<b>while s[length(s)]=' ' do delete(s,length(s),1);</b>
<b>while pos(' ',s)<>0 do delete(s,pos(' ',s),1);</b>
<b>assign(f,fo);</b>


<b>rewrite(f);</b>


<b>if s= '' then d:=0 else d:=1;</b>


<b>for i:=1 to length(s) do if s[i]=' ' then d:=d+1;</b>
<b>writeln(f,d);</b>


<b>for i:=1 to length(s) do</b>
<b> </b> <b>begin</b>


<b> </b> <b>write(f,s[i]);</b>


</div>
<span class='text_page_counter'>(39)</span><div class='page_container' data-page=39>

<b> </b> <b>end;</b>
<b>close(f);</b>


<b>end;</b>


<b>begin</b>
<b>doc;</b>
<b>xl;</b>
<b>end.</b>


<b>C©u 14: D·y con </b>–<b> DAYCON.PAS</b>


Cho hai dãy số thực a1, a2, ... ,an (1) và b1, b2, ... ,bm (2). Dãy (1) đợc gọi là


dãy con của dãy (2) nếu bỏ đi k (k>=0) phần tử trong dãy (2) thì ta đợc dãy (1).
Chằng hạn: dãy 1, 3, 5 là dãy con của dãy 0,1, 2, 1, 4, 3, 5, 7.


<i>Yêu cầu:</i> Với hai dãy số cho trớc, hãy xác định xem dãy (1) có phải là dóy con
ca dóy (2) hóy khụng.


<i>Dữ liệu vào:</i> Cho trong file DAYCON.INP cã cÊu tróc nh sau:
-Dßng 1: Ghi sè N là số lợng phần tử của dÃy (1). (1<=N<=1000)
-Dòng 2: Ghi N sè a1 a2 ... an, c¸c sè ghi cách nhau một dấu cách.


-Dòng 3: Ghi số M là số lợng phần tử của dÃy (2). (1<=M<=1000)
-Dòng 4: Ghi M sè b1 b2 ... bm, c¸c sè ghi cách nhau một dấu cách.


<i>Dữ liệu ra:</i> Ghi ra file DAYCON.OUT theo cÊu tróc nh sau:


-Dßng 1: Ghi ký tù ‘Y’ nÕu d·y (1) lµ d·y con cđa d·y (2), ngợc lại ghi ký tự N


<i><b>Ví dụ:</b></i>



DAYCON.INP DAYCON.OUT


3 Y


1 3 5
8


0 1 2 1 4 3 5 7
Chơng trình gợi ý


<b>const fi='daycon.in6';</b>
<b> fo='daycon.ou6';</b>


<b>type mmcr=array[1..1000] of real;</b>
<b>var f:text;</b>


<b> a,b:mmcr;</b>
<b> n,m:word;</b>
<b>procedure doc;</b>
<b>var i:word;</b>
<b>begin</b>


<b> assign(f,fi); reset(f);</b>
<b> readln(f,n);</b>


<b> for i:=1 to n do read(f,a[i]);</b>
<b> readln(f);</b>


<b> readln(f,m);</b>



<b> for i:=1 to m do read(f,b[i]);</b>
<b> close(f);</b>


<b>end;</b>


<b>function tim(x:real;var j:word):word;</b>
<b>begin</b>


<b> while (j<=m) and (x<>b[j]) do j:=j+1;</b>
<b> tim:=j;</b>


<b>end;</b>


<b>procedure xl;</b>


</div>
<span class='text_page_counter'>(40)</span><div class='page_container' data-page=40>

<b>j:=1; kt:='Y';</b>
<b>for i:=1 to n do</b>
<b> begin</b>


<b> if (tim(a[i],j)>m) then kt:='N';</b>
<b> end;</b>


<b>assign(f,fo); rewrite(f);</b>
<b>writeln(f,kt);</b>


<b>close(f);</b>
<b>end;</b>
<b>begin</b>


<b>doc;</b>


<b>xl;</b>
<b>readln;</b>
<b>end.</b>


<b>Câu 15: Đếm các hình vng nhìn thấy đợc từ gốc tọa độ. SQUARES.PAS</b>
Trong mặt phẳng tọa độ cho N hình vng có các cạnh song song với các
trục tọa độ. Các hình vng đợc đánh số từ 1 đến N. Các đỉnh của các hình
vng đều có tọa độ ngun và khơng có hai hình vng nào có điểm chung.


Một hình vng đợc gọi là nhìn thấy đợc từ gốc tọa độ O=(0,0), nếu tìm
đ-ợc hai điểm A, B trên một số các cạnh của hình vng sao cho phần trong của
tam giác OAB khơng có điểm chung với bất kỳ hình vng nào trong các hình
vng cịn lại.


<i><b>u cầu:</b></i> Tìm số lợng hình vng nhìn thấy c t gc ta .


<i><b>Dữ liệu vào:</b></i> Cho trong file SQUARES.INP cã cÊu tróc nh sau:
-Dßng 1: Ghi sè nguyên N (1<=N<=1000), là số lợng hình vuông


-Trong N dòng tiếp theo: dòng thứ i ghi 3 số nguyên Xi Yi Li, trong đó (Xi , Yi)


là tọa độ của đỉnh ở góc dới bên trái của hình vng thứ i, Li là độ dài cạnh ca


hình vuông thứ i. Các số ghi cách nhau một dấu cách. (1<= Xi Yi Li <=1000)
<i><b>Dữ liệu ra:</b></i> Ghi ra file SQUARES.OUT theo cÊu tróc nh sau:


-Dịng 1: Ghi số M, là số lợng hình vng nhìn thấy đợc từ gốc tọa độ.


-Dòng 2: Ghi M số, là số hiệu của các hình vng nhìn thấy đợc từ gốc tọa độ.
Các số ghi cách nhau một dấu cách.



VÝ dô:


SQUARES.INP SQUARES.OUT SQUARES.INP SQUARES.OUT


3 3 4 2


2 6 3 1 2 3 1 2 1 1 2


1 4 1 3 1 1


3 4 1 2 4 2


3 7 1
Chơng trình gợi ý:


<b>{$r+}</b>


<b>program Cac_hinh_chu_nhat_co_the_nhin_thay_tu_goc_toa_do;</b>
<b>const fi='squares.in7';</b>


<b> fo='squares.ou7';</b>


<b>type ii=integer; bo=boolean; rr=real;</b>
<b> mmc=array[0..1001] of ii;</b>


<b> mmc1=array[0..1001] of bo;</b>
<b> mmc2=array[0..1001] of rr;</b>


<b>var x1,y1,x2,y2,e:mmc; b:mmc1; g1,g2:mmc2;</b>


<b> n:ii;</b>


</div>
<span class='text_page_counter'>(41)</span><div class='page_container' data-page=41>

<b>begin</b>


<b> assign(f,fi);</b>
<b> reset(f);</b>
<b> readln(f,n);</b>
<b> for i:=1 to n do</b>
<b> begin</b>


<b> readln(f,x,y,l);</b>
<b> x1[i]:=x; </b>


<b>y1[i]:=y+l;</b>


<b> x2[i]:=x+l; </b>
<b>y2[i]:=y;</b>


<b> end;</b>
<b> close(f);</b>
<b>end;</b>


<b>procedure sort(l,r:integer);</b>
<b>var i,j,x,y:integer;</b>


<b>begin</b>
<b> i:=l;</b>
<b> j:=r;</b>


<b> x:=x1[(l+r) div 2]+ y1[(l+r) div 2];</b>


<b> repeat</b>


<b> while x1[i]+y1[i]<x do i:=i+1;</b>
<b> while x<x1[j]+y1[j] do j:=j-1;</b>
<b> if i<=j then</b>


<b> begin</b>


<b> y:=x1[i]; x1[i]:=x1[j]; x1[j]:=y;</b>
<b> y:=y1[i]; y1[i]:=y1[j]; y1[j]:=y;</b>
<b> y:=x2[i]; x2[i]:=x2[j]; x2[j]:=y;</b>
<b> y:=y2[i]; y2[i]:=y2[j]; y2[j]:=y;</b>
<b> y:=e[i]; e[i]:=e[j]; e[j]:=y;</b>
<b> i:=i+1; j:=j-1;</b>


<b> end;</b>
<b> until i>j;</b>


<b> if l<j then Sort(l,j);</b>
<b> if i<r then Sort(i,r);</b>
<b>end;</b>


<b>procedure tinhgoc;</b>
<b>var i:ii;</b>


<b>begin</b>


<b> for i:=1 to n do</b>
<b> begin</b>



<b> if x1[i]=0 then g1[i]:=90</b>


<b> else g1[i]:=arctan(y1[i]/x1[i]);</b>
<b> if x2[i]=0 then g2[i]:=90</b>


<b> else g2[i]:=arctan(y2[i]/x2[i]);</b>
<b> end;</b>


<b>end;</b>


<b>procedure quet(x,y:real);</b>
<b>var i:ii;</b>


<b>begin</b>


</div>
<span class='text_page_counter'>(42)</span><div class='page_container' data-page=42>

<b> if (g1[i]>x) and (g2[i]<y) then</b>
<b> begin</b>


<b> b[i]:=true;</b>
<b> quet(x,g2[i]);</b>
<b> quet(g1[i],y);</b>
<b> break;</b>


<b> end;</b>
<b>end;</b>


<b>procedure xl;</b>
<b>var i,j,dem:ii;</b>
<b>begin</b>



<b> for i:=1 to n do e[i]:=i;</b>
<b> writeln;</b>


<b> sort(1,n);</b>
<b> tinhgoc;</b>


<b> fillchar(b,sizeof(b),false);</b>
<b> quet(0,pi/2);</b>


<b> dem:=0;</b>


<b> for i:=1 to n do</b>


<b> if b[i] then inc(dem);</b>
<b> assign(f,fo);</b>


<b> rewrite(f);</b>
<b> writeln(f,dem);</b>
<b> for i:=1 to n do</b>


<b> if b[i] then write(f,e[i],' ');</b>
<b> close(f);</b>


<b>end;</b>
<b>begin</b>
<b> doc;</b>
<b> xl;</b>
<b>end.</b>


<b>Câu 16: Số nguyên tố cùng nhau - NT.PAS</b>



Tìm tất cả các số tự nhiên X có ba chữ số sao cho khi đảo ngợc trật tự các
chữ số của X ta sẽ thu đợc một số nguyên Y mà X và Y là hai số ngun tố cùng
nhau.


VÝ dơ: X =122 vµ Y= 221


Dữ liệu ra: Ghi ra file NT.OUT theo cấu trúc nh sau:
<i>- Dòng 1:</i> Ghi số nguyên dơng N, là số lợng số X tìm đợc.


<i>- Dịng 2:</i> Ghi N số tìm đợc. Các số ghi cách nhau một dấu cách.
Chơng trình gợi ý:


<b>const fo='NT.OUT';</b>
<b> nn=901;</b>


<b>type mmcw=array[0..901] of word;</b>
<b>var n:word; s:mmcw;</b>


<b>function uscln(a,b:word):word;</b>
<b>var r:word;</b>


<b>begin</b>


<b>while b>0 do</b>
<b> begin </b>


<b>r:=a mod b; </b>
<b>a:=b; </b>



</div>
<span class='text_page_counter'>(43)</span><div class='page_container' data-page=43>

<b>uscln:=a;</b>
<b>end;</b>


<b>function dao(x:word):word;</b>
<b>var y:word;</b>


<b>begin</b>
<b> y:=0;</b>


<b> while x>0 do</b>
<b> begin </b>


<b>y:=10*y+(x mod 10); </b>
<b>x:=x div 10; </b>


<b>end;</b>
<b>dao:=y;</b>
<b>end;</b>


<b>function tim:word;</b>
<b>var x,d:word;</b>
<b>begin</b>


<b>d:=0;</b>


<b>for x:=100 to 999 do</b>


<b> if uscln(x,dao(x))=1 then</b>
<b> </b> <b>begin </b>



<b>d:=d+1; </b>
<b>s[d]:=x; </b>
<b>end;</b>


<b>tim:=d;</b>
<b>end;</b>


<b>procedure xuat;</b>
<b>var f:text; i:word;</b>
<b>begin</b>


<b>n:=tim;</b>


<b>assign(f,fo);</b>
<b>rewrite(f);</b>
<b>writeln(f,n);</b>


<b>for i:=1 to n do write(f,s[i],' ');</b>
<b>close(f);</b>


<b>end;</b>
<b>begin</b>


<b>xuat;</b>
<b>end.</b>


<b>Câu 17. Tìm số s¸t sau - SOSATSAU.PAS</b>


Cho số tự nhiên A có N chữ số. Hãy hốn vị các chữ số trong A để thu đợc số
B thoả mãn đồng thời hai điều kiện sau:



- B lín h¬n A.
- B nhỏ nhất.


Dữ liệu vào: Cho trong file Sosatsau.inp có cấu trúc nh sau:


<i>- Dòng 1:</i> Ghi số N là số lợng chữ số của A (0<N<=1000).


<i>- Dòng 2:</i> Ghi các chữ số của số A, giữa các chữ số không có dấu cách.
Dữ liệu ra: Ghi vào file Sosatsau.out theo cÊu tróc:


<i>- Dịng 1:</i> Ghi số B tìm đợc, giữa các chữ số khơng có dấu cách. Nếu khơng
tìm đợc số B thì ghi chữ số 0.


VÝ dơ


Sosatsau.inp Sosatsau.out Sosatsau.inp Sosatsau.out


6


526431


531246 2


21


</div>
<span class='text_page_counter'>(44)</span><div class='page_container' data-page=44>

Chơng trình gợi ý:


<b>const</b>



<b> max=1000;</b>


<b> fi='sosatsau.inp';</b>
<b> fo='sosatsau.out';</b>
<b>var</b>


<b> a:array[0..max]of char;</b>
<b> n:integer;</b>


<b> kt:boolean;</b>
<b>Procedure docdl;</b>
<b>var</b>


<b> f:text;</b>
<b> c:char;</b>
<b> i:integer;</b>
<b>begin</b>


<b> assign(f,fi);</b>
<b> reset(f);</b>
<b> readln(f,n);</b>
<b> i:=0;</b>


<b> while not eof(f) do</b>
<b> begin</b>


<b> read(f,c);</b>


<b> if(c>='0') and(c<='9') then</b>
<b> begin</b>



<b> inc(i);</b>
<b> a[i]:=c;</b>
<b> end;</b>


<b> end;</b>
<b> close(f);</b>
<b>end;</b>


<b>procedure kiemtra;</b>
<b>var</b>


<b> i,j:integer;</b>
<b> tg:char;</b>
<b>begin</b>


<b> kt:=false;</b>
<b> i:=n-1;</b>


<b> while a[i]>=a[i+1] do</b>
<b> dec(i);</b>


<b> if i<>0 then</b>
<b> begin</b>


<b> j:=n;</b>


<b> while a[j]<=a[i] do</b>
<b> dec(j);</b>



<b> tg:=a[i];</b>
<b> a[i]:=a[j];</b>
<b> a[j]:=tg;</b>
<b> inc(i);</b>
<b> j:=n;</b>


<b> while j>i do</b>
<b> begin</b>


</div>
<span class='text_page_counter'>(45)</span><div class='page_container' data-page=45>

<b> a[j]:=tg;</b>
<b> inc(i);</b>
<b> dec(j);</b>
<b> end;</b>


<b> kt:=true;</b>
<b> end;</b>


<b>end;</b>


<b>procedure xuatdl;</b>
<b>var</b>


<b> f:text;</b>
<b> i:integer;</b>
<b>begin</b>


<b> assign(f,fo);</b>
<b> rewrite(f);</b>
<b> if kt then</b>



<b> for i:=1 to n do</b>
<b> write(f,a[i])</b>
<b> else</b>


<b> write(f,'0');</b>
<b> close(f);</b>


<b>end;</b>
<b>begin</b>


<b> docdl;</b>
<b> kiemtra;</b>
<b> xuatdl;</b>
<b>end.</b>


Test gợi ý:


<b>SOSATSAU.INP</b> <b>SOSATSAU.OUT</b>


<b>5</b>
<b>54321</b>


<b>0</b>
<b>6</b>


<b>724356</b>


<b>724365</b>
<b>1</b>



<b>7</b>


<b>0</b>
<b>4</b>


<b>1234</b>


<b>1243</b>


<b>Câu 18. Giải mà chuỗi nhị phân - NHIPHAN.PAS</b>


Mọi thơng tin đều đợc mã hố dới dạng một chuỗi số nhị phân. Để nâng cao
độ tin cậy khi truyền tin, mỗi bít đợc biểu diễn lặp lại 3 lần. Ví dụ, các bít tin
‘011’ đợc biểu diễn thành ‘000111111’ để thực hiện truyền. Do nhiễu của mơi
tr-ờng nên khi về đến đích, các bít tin có thể bị sai lệch. Vì vậy, khi nhận đợc thơng
tin cứ mỗi đoạn 3 bít đợc giải mã thành một bít. Bít này có giá trị 0 nếu trong
nhóm 3 bít xuất hiện ít nhất 2 bít 0, bít này có giá trị 1 nếu trong nhóm 3 bít xuất
hiện ít nhất 2 bít 1. Ví dụ, nếu các bít tin nhận đợc là ‘000110010011’, sau khi đã
giải mã ta thu đợc ‘0101’.


<b>Yêu cầu:</b> Cho chuỗi nhị phân biểu diễn thông tin nhận đợc, hãy giải mã chuỗi
nhị phõn ú.


<b>Dữ liệu vào:</b> Cho trong file Nhiphan.inp có cấu trúc nh sau:


<i>-Dòng 1:</i> Ghi chuỗi nhị phân cần giải mÃ, là một dÃy các số 0, 1 ghi liền nhau.
<b>D÷ liƯu ra:</b> Ghi trong file Nhiphan.out theo cÊu tróc nh sau:


<i>-Dòng 1.</i> Ghi chuỗi nhị phân đã đợc giải mã, là một dãy các số 0, 1 ghi lin
nhau.



</div>
<span class='text_page_counter'>(46)</span><div class='page_container' data-page=46>

Nhiphan.inp Nhiphan.out


001111010110111000 010110
<b>Chơng trình gợi ý:</b>


<b>const</b>


<b> fi='nhiphan.inp';</b>
<b> fo='nhiphan.out';</b>
<b>var</b>


<b> st,s1:string;</b>
<b>procedure docdl;</b>
<b>var</b>


<b> f:text;</b>
<b>begin</b>


<b> assign(f,fi);</b>
<b> reset(f);</b>
<b> readln(f,st);</b>
<b> close(f);</b>
<b>end;</b>


<b>function mahoa(kt1,kt2,kt3:char):char;</b>
<b>var</b>


<b> t:byte;</b>
<b>begin</b>


<b> t:=0;</b>


<b> if kt1='1' then</b>
<b> t:=t+1;</b>
<b> if kt2='1' then</b>
<b> t:=t+1;</b>
<b> if kt3='1' then</b>
<b> t:=t+1;</b>
<b> if t>=2 then</b>
<b> mahoa:='1'</b>
<b> else</b>


<b> mahoa:='0';</b>
<b>end;</b>


<b>procedure xuli;</b>
<b>var</b>


<b> ll,l,i:integer;</b>
<b>begin</b>


<b> ll:=length(st);</b>
<b> l:=1;</b>


<b> s1:='';</b>


<b> while l<ll do</b>
<b> begin</b>


<b> s1:=s1+mahoa(st[l],st[l+1],st[l+2]) ;</b>


<b> l:=l+3;</b>


<b> end;</b>
<b>end;</b>


<b>procedure xuatdl;</b>
<b>var</b>


<b> f:text;</b>
<b>begin</b>


<b> assign(f,fo);</b>
<b> rewrite(f);</b>
<b> writeln(f,s1);</b>
<b> close(f);</b>
<b>end;</b>


<b>begin</b>


</div>
<span class='text_page_counter'>(47)</span><div class='page_container' data-page=47>

<b>xuatdl;</b>
<b>end.</b>


Test gỵi ý:


NHIPHAN.INP NHIPHAN .OUT
101111000011011100010101 11011001


101010110111000101010001110 101101001
000001111010110111010101011000 0010110110
001111000001100111010110111000 0100010110


001010100010000100001 0000000
000011110011111110101101110001 0111111110


<b>C©u 19: D·y con - DAYCON.PAS</b>


Cho hai dãy số thực a1, a2, ... ,an (1) và b1, b2, ... ,bm (2). Dãy (1) đợc gọi là


dãy con của dãy (2) nếu bỏ đi k phần tử trong dãy (2) thì ta đợc dãy (1).
<b>Ví dụ</b>: Dãy 1, 3, 5 là một dãy con của dãy 0,1, 2, 1, 4, 3, 5, 7.


<b>Yêu cầu:</b> Với hai dãy số cho trớc, hãy xác định xem dãy (1) có phải là dãy
con của dãy (2) hay khơng.


<b>D÷ liƯu vµo:</b> Cho trong file DAYCON.INP cã cÊu tróc nh sau:


<i>- Dòng 1:</i> Ghi số N là số lợng phần tử cđa d·y (1) (1<=N<=1000).
<i>- Dßng 2:</i> Ghi N sè a1 a2 ... an, c¸c sè ghi c¸ch nhau mét dÊu cách.


<i>- Dòng 3:</i> Ghi số M là số lợng phần tư cđa d·y (2) (1<=M<=1000).
<i>- Dßng 4:</i> Ghi M sè b1 b2 ... bm, c¸c sè ghi c¸ch nhau mét dấu cách.


<b>Dữ liệu ra:</b> Ghi ra file DAYCON.OUT theo cấu tróc nh sau:


<i>- Dßng 1:</i> Ghi ký tù ‘Y’ nÕu dÃy (1) là dÃy con của dÃy (2), ngợc lại ghi ‘N’
VÝ dô:


DAYCON.INP DAYCON.OUT
3


1 3 5


8


0 1 2 1 4 3 5 7
Y


Chơng tình gợi ý:


<b>const fi='daycon.in7';</b>
<b> fo='daycon.ou7';</b>


<b>type mmcr=array[1..1000] of real;</b>
<b>var f:text;</b>


<b> a,b:mmcr;</b>
<b> n,m:word;</b>
<b>procedure doc;</b>
<b>var i:word;</b>
<b>begin</b>


<b> assign(f,fi); </b>
<b>reset(f);</b>
<b> readln(f,n);</b>


<b> for i:=1 to n do read(f,a[i]);</b>


<b> </b> <b>readln(f);</b>


<b> readln(f,m);</b>


<b> for i:=1 to m do read(f,b[i]);</b>


<b> close(f);</b>


<b>end;</b>


<b>function tim(x:real;var j:word):word;</b>
<b>begin</b>


</div>
<span class='text_page_counter'>(48)</span><div class='page_container' data-page=48>

<b>end;</b>


<b>procedure xl;</b>


<b>var i,j:word; kt:char;</b>
<b>begin</b>


<b>j:=1; </b>
<b>kt:='Y';</b>


<b>for i:=1 to n do</b>


<b> </b> <b>begin</b>


<b> </b> <b>if (tim(a[i],j)>m) then kt:='N';</b>


<b> </b> <b>end;</b>


<b>assign(f,fo);</b>
<b>rewrite(f);</b>
<b>writeln(f,kt);</b>
<b>close(f);</b>
<b>end;</b>



<b>begin</b>
<b>doc;</b>
<b>xl;</b>
<b>readln;</b>
<b>end.</b>


<b>Test gỵi ý:</b>


DAYCON.INP DAYCON .OUT


<b>4</b>


<b>1 2 3 4</b>
<b>3</b>


<b>1 2 3</b>


<b>N</b>


<b>4</b>


<b>1 2 3 4</b>
<b>4</b>


<b>1 2 3 4</b>


<b>Y</b>


<b>1</b>


<b>1</b>
<b>1</b>
<b>1</b>


<b>Y</b>


<b>1</b>
<b>1</b>
<b>1</b>
<b>4</b>


<b>N</b>


<b>3</b>
<b>1 3 5</b>
<b>5</b>


<b>1 5 3 6 7</b>


<b>N</b>


<b>5</b>


<b>1 4 6 8 9</b>
<b>7</b>


<b>1 2 4 5 6 8 9</b>


<b>Y</b>



<b>3</b>
<b>1 4 9</b>
<b>9</b>


<b>0 1 3 4 2 7 8 9 10</b>
<b>Y</b>


<b>Câu 20: Sắp xếp xâu - STR.PAS</b>


Cho một xâu mẫu S gồm N ký tự đợc lấy từ tập các ký tự ‘A’...‘Z’. Với một
cặp số nguyên (i,j) (1<=i,j<=N), ta tạo ra một xâu thứ cấp S’ bằng cách đổi chỗ
ký tự thứ i với ký tự thứ j của xâu mẫu S. Với M cặp số (i,j) ta sẽ thu đợc M xâu
thứ cấp.


</div>
<span class='text_page_counter'>(49)</span><div class='page_container' data-page=49>

<i>- Dòng 1:</i> Ghi giá trị N, là số ký tự của xâu S (1<=N<=500)
<i>- Dòng 2:</i> Ghi xâu mẫu S.


<i>- Dòng 3:</i> Ghi giá trị M, là số lợng các cặp số (i, j) (1<=M<=500)


<i>- M dòng tiếp theo:</i> Mỗi dòng ghi một cặp số i, j lần lợt là chỉ số của ký tự
thứ i và chỉ số của ký tự thứ j cần đổi chỗ của xâu S. Hai số ghi cách nhau một
dấu cách.


<b>D÷ liƯu ra:</b> Ghi ra file STR.OUT theo cÊu tróc nh sau:


<i>- M dịng:</i> Mỗi dịng ghi một xâu thứ cấp, các dòng đợc sắp tăng dần theo thứ
tự từ điển.


VÝ dô:



STR.INP STR.OUT
5


ABCDA
3


2 4
1 5
3 3


</div>

<!--links-->

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×