1. Trang chủ
  2. » Luận Văn - Báo Cáo

Báo cáo chuyên đề BDGV tin học (Dạy học sinh giỏi)

43 1,1K 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 43
Dung lượng 225,5 KB

Nội dung

Tài liệu này là chuyên đề bồi dưỡng giáo viên cốt cán môn tin học bậc THCS của Sở GDĐT. Nội dung tập trung bổ sung các kiến thức nâng cao trong kỹ thuật lập trình Pascal phục vụ dạy HS giỏi. Thuật toán đệ qui quay lui, nhánh cận được sử dụng giải các bài toán: Cân vật, rót nước, bảng số, vòng trong nguyên tố...Các thuật toán đồ thị đơn giản ứng dụng trong giải bài toán tối ưu.

Trang 1

Chuyên đề 3 BỒI DƯỠNG HỌC SINH GIỎI

I BỔ SUNG KIẾN THỨC CƠ BẢN VỀ NGÔN NGỮ LẬP TRÌNH PASCAL 1.1 Sự cần thiết phải có kiểu mảng

Xét bài toán 1 “ Nhập vào nhiệt độ trung bình của mỗi ngày trong tuần, đưa

ra nhiệt độ trung bình của tuần và số ngày trong tuần có nhiệt độ trung bình cao hơnnhiệt độ TB của tuần”

Cần khai báo bao nhiêu biến lưu trữ nhiệt độ ngày ? Cần 7 biến

Nếu yêu cầu bài toán không là 7 ngày mà là 1 năm thì có giải quyết đượckhông?

 Bản chất thuật toán không có gì thay đổi nhưng phải khai báo quá nhiều biến,chương trình phải viết nhiều câu lệnh nên rất dài

 Để khắc phục những hạn chế trên, NNLT ghép chung 7 biến trên thành mộtdãy, đặt cho nó chung một tên và đánh dấu cho mỗi phần tử là một chỉ số Đó chính

là kiểu dữ liệu mảng

1.2 Kiểu mảng một chiều

Khái niệm: Mảng một chiều là một dãy hữu hạn các phần tử có cùng kiểu dữ

liệu

Mảng là kiểu dữ liệu có cấu trúc

Khi xây dựng kiểu mảng một chiều cần xác định:

- Tên mảng một chiều

- Số lượng phần tử trong mảng

- Kiểu dữ liệu của phần tử

- Cách khai báo biến mảng một chiều

- Cách truy cập vào từng phần tử của mảng

a Khai báo

Cách 1: Khai báo biến trực tiếp:

Var <Tên biến mảng> : array [kiểu chỉ số] of <kiểu phần tử>;

Cách 2: khai báo biến gián tiếp

- Khai báo kiểu dữ liệu mảng

Type <Tên kiểu mảng> = array [Kiểu chỉ số] of <Kiểu phần tử>;

Var <Tên biến mảng> : <tên kiểu mảng>;

Trong đó:

- Tên kiểu mảng, Tên biến mảng do người lập trình đặt theo qui tắc đặt tên

Trang 2

- Kiểu chỉ số thường là một đoạn số nguyên liên tục n1 n2 (n1<=n2) n1 gọi làchỉ số đầu, n2 gọi là chỉ số cuối Kiểu chỉ số phải có kiểu đếm được.

- Kiếu phần tử là các kiểu dữ liệu chuẩn và kiểu có cấu trúc ngoại trừ kiểu file

Ví dụ:

+ Khai báo biến lưu trữ nhiệt độ từng ngày trong 1 năm

C1: Var NhietDo= array[1 366] of Real;

C2: Type Kmang1= array[1 366] of Real;

b Qui tắc tham chiếu đến phần tử mảng

<Tên biến mảng>[<Chỉ số>]

Trong đó: n1<= Chỉ số <=n2Lưu ý: chỉ số <n1 hoặc > n2 sẽ saiKhi tham chiếu đến phần tử xem như 1 biến có kiểu dữ liệu của phần từ

Ví dụ:

+ Nhiệt độ ngày đầu tiên: NhietDo[1]

+ Nhiệt độ ngày 1 tháng 2: NhietDo[32]

+ Xem nhiệt độ từ ngày 1 đến ngày n

For i:= 1 to n do Write(Nhietdo[i]:6:2)

+ Tính tổng nhiệt độ trong năm

Tong:=0;

For i:= 1 to n do Tong:= Tong +Nhietdo[i];

+ Đếm số ngày có nhiệt độ lớn hơn nhiệt độ TB

Trang 3

Var <tên mảng>: array [Kiểu chỉ số dòng, kiểu chỉ số cột] of <kiểu phần tử>;

Cách 2: Khai báo gián tiếp:

Type <tên kiểu mảng>= array [Kiểu chỉ số dòng, kiểu chỉ số cột] of <kiểu phần tử>;

Var <tên mảng>:<tên kiểu mảng>;

Ví dụ: Cho mảng a gồm 5 dòng, 4 cột, kiểu số nguyên ta khai báo như sau:

Type mang=array [1 5,1 4] of integer;

c Biến đổi các số dương trong mảng thành số 1, các số còn lại thành số 0

d Tìm giá trị lớn nhất (bé nhất), tìm vị trí phần tử đầu tiên có giá trị bé nhất (số dương bé nhất, số âm lớn nhất, vị trí đầu tiên của số lẻ, vị trí cuối cùng của

số chẵn)

e Nhập một số nguyên x Tìm vị trí xuất hiện của x nếu có, ngược lại thì thông báo không có số này ( đếm xem số này xuất hiện bao nhiêu lần trong mảng)

f Đổi chỗ giữa số lẻ đầu tiên và số chẵn cuối cùng của mảng nếu có

g Tìm vị trí của số có giá trị “gần” với giá trị trung bình cộng nhất Khoảng cách giữa 2 số là trị tuyệt đối của hiệu 2 số đó

2: Viết chương trình nhập n, Sinh một dãy ngẫu nhiên n số từ 1 đến 100 sau đó xử

Hàm random(100): sinh số từ 0 đến 100

a Nhập vị trí k, xóa phần tử ở vị trí thứ k Đưa dãy đã xóa ra màn hình

b Nhập vị trí k và một số x tùy ý Chèn số x vào vị trí k Đưa dãy đã chèn ra màn hình

c Sắp xếp để thu được dãy tăng dần, (dãy giảm dần) Đưa dãy đã sắp xếp ra màn hình Cho biết có bao nhiêu lần hoán chuyển 2 phần tử trong dãy khi sắpxếp

Trang 4

d Nhập 0<k<n+1, sắp xếp các số từ vị trí 1 đến k thành dãy tăng, từ vị trí k+1 đến n thành dãy giảm dần.

e Sắp xếp thành một dãy tăng dần Nhập số nguyên x,

chèn x vào tại vị trí thích hợp để dãy vẫn là một dãy

tăng Đưa dãy đã chèn ra màn hình

f Kiểm tra dãy có là dãy tăng không? (dãy là các số lẻ,

dãy là cấp số cộng, là dãy fibonacy, là các số nguyên

d Tìm phần tử lớn nhất và phần tử nhỏ nhất hoán đổi giá trị hai phần tử này

2 Nhập n <20, đưa ra ma hình ma trận hình xoắn ốc ví dụ với n =5 như hình trên

5 Nhập n, đưa ra màn hình tam giác pascal Với n =5 đưa ra kết quả sau

Trang 5

- Xâu là một dãy kí tự trong bảng mã ASCII.

- Mỗi kí tự gọi là một phần tử của xâu

- Số lượng kí tự trong xâu được gọi là độ dài của xâu

- Xâu có độ dài bằng 0 gọi là xâu rỗng

- Tham chiếu tơí phần tử trong xâu được xác định thông qua chỉ số của phần tử trong xâu

- Chỉ số phần tử trong xâu được đánh số là 1

Ví dụ: Những đối tượng cần khai báo kiểu xâu: Họ tên, tên môn học, địa chỉ,quê quán

2.3 Khai báo biến xâu

Var <tên biến> : String [độ dài lớn nhất của xâu ] ;

+ Tham chiếu tới từng kí tự xâu: <tên biến xâu>[chỉ số]

+ Ghép xâu: + : Ghép nhiều xâu lại thành 1 xâu

VD: ‘Ha’ +’ noi’ cho kết quả ‘Ha noi’

+ Length(s): độ dài xâu

+ Delete(s, 5, 2): xóa xâu s từ vị trí thứ 5 và xóa 2 ký tự

+ Insert(S1, S2, vt) : chèn S1 vào S2 bắt đầu từ vị trí vt

Trang 6

+ Copy(S, vt, N) tạo xâu gồm N kí tự liên tiếp bắt đầu từ vt của xâu S + Pos(S1,S2): trả về vị trí xuất hiện đầu tiên của xâu S1 trong xâu S2

2 Nhập 1 xâu họ tên đầy đủ (theo cách đặt tên nguời việt) Sau đó in ra màn

hình Họ,Họ đệm, Tên của nguời đó

3 Nhập vào 1 xâu s kiểm tra xâu đã nhập có đối xứng không

4 Đọc một loạt các kí tự từ bàn phím cho đến khi ấn Enter thì ngừng nhập In ra

5 Xét một dãy các chữ số A nhận được từ cách ghép liên tiếp các chữ số

nguyên dương liên tiếp tăng dần bắt đầu từ 1,2,3, 4 đến số m cho trước (m>30 và m<=1000) Cho biết một số nguyên dương N hãy tìm vị trí đầu tiên của số N trong dãy A Biết rằng vị trí trong dãy A được tính từ 1 nếu không tìm thấy số N trong dãy A thì trả lời vị trí là 0

Trang 7

 Có thể dùng nhiều mảng 1 chiều để lưu trữ, mỗi mảng lưu trữ 1 cột

 khi lấy thông tin người thứ 3 cần phải làm với nhiều mảng Bất tiện

 Ngôn ngữ lập trình bậc cao có cách tốt hơn để quản lý dữ liệu trên gọi là Kiểubản ghi Một hàng là 1 biến có kiểu bản ghi, mỗi cột thể hiện thuộc tính của đốitượng gọi là Trường

3.2 Một số khái niệm

- Kiểu bản ghi (Record) là một kiểu dữ liệu có cấu trúc

- Một bản ghi gồm các thành phần (gọi là trường), các trường có thể thuộc cáckiểu dữ liệu khác nhau

- Kiểu bản ghi dùng để mô tả nhiều đối tượng có cùng một số thuộc tính

- Khi làm việc với bản ghi cần biết;

+ Tên kiểu bản ghi;

+ Tên các trường;

+ Kiểu dữ liệu của mỗi trường;

+ Cách khai báo biến;

+ Cách tham chiếu đến trường

3.3 Khai báo

Khai báo kiểu:

Type <tên kiểu bản ghi> = record

<tên trường 1>:<kiểu trường 1>;

………

<tên trường n>:<kiểu trường n>;

End;

Khai báo biến:

Var <tên biến>: <tên kiểu bản ghi>;

Trang 8

Var hs, hs1, hs2: HocSinh;

+ Khai báo biến lưu trữ dữ liệu cho cả lớp

Var Lop: array [1 50] of HocSinh;

3.4 Tham chiếu đến từng trường

Khi làm việc với bản ghi tức là làm viêc với từng thành phần của nó

Qui tắc tham chiếu đến từng trường

<tên biến bản ghi> <tên trường>

Hoăc

WITH <Tên biến kiểu bản ghi> DO <Câu lệnh tác động đến tên trường>;

Ví dụ:

+ Biến hs: hs.HoTen, hs.toan

+ Biến Lop chúng ta cần tham chiếu đến phần tử mang Lop[i] sau đó tham chiếuđến trường: Lop[i].HoTen

3.5 Gán giá trị

Có hai cách để đưa giá trị cho bản ghi

a) Dùng lệnh gán trực tiếp: A:=B

Yêu cầu A, B cùng kiểu

b) Đưa giá trị cho từng trường tùy thuộc vào kiểu dữ liệu của từng trường

- Nếu trường có kiểu dữ liệu cơ sở ta có thể gán như sau:

<Tên biến> <Tên trường>:= <biểu thức>;

Readln(<Tên biến> <Tên trường>);

Ví dụ: Cho biến HS lưu trữ thông tin như sau:

Hs.NgaySinh:=’10-10-1995’

Hs Toan:=8; Hs.Ly:=9; Hs.Hoa:=7; Hs.Tin:=10

+ Xem tên, điểm TB của 4 môn trong biến hs

4.2 Vai trò của kiểu tệp

Trang 9

+ Kiểu dữ liệu tệp tin giúp chúng ta trao đổi dữ liệu với bộ nhớ ngoài thông qua các tệp tin.

+ Tệp được lưu trữ lâu dài ở bộ nhớ ngoài, lượng dữ liệu lưu trữ trên tệp có thểrất lớn và chỉ phụ thuộc vào dung lượng ổ đĩa

4.3 Phân loại tệp và thao tác với tệp

Các loại tệp tin đã biết: văn bản, chương trình, hình ảnh, âm thanh

Đọc từ đầu đến cuối  tệp văn bản

Đọc từng phần của tệp như âm thanh có thể nghe từ nửa bài  tệp cấu trúc+ Tệp văn bản (text): dữ liệu ghi vào tệp dưới dạng từng kí tự Đọc và ghi tệp được thực hiện tuần tự, từ đầu đến cuối tệp

+ Tệp có cấu trúc: dữ liệu được lưu trữ theo cấu truc nhất định Đọc và ghi dữ liệu có thể làm trực tiếp đến từng phần tử

4.4 Thao tác với tệp văn bản

Với tệp tin cần làm gì?  Đọc dữ liệu đưa ra màn hình, ghi dữ liệu được vào

tệp tin

Các bước thao tác với tệp văn bản:

Bước 1: Khai báo biến tệp

Var <Tên biến tệp> : Text;

Ví dụ: Var Tep1, Tep2: Text;

Đọc: đọc tuần tự bắt đầu từ đầu tệp, nếu tệp chưa có trên đĩa sẽ báo lỗi

Bước 4: Các thao tác đọc và ghi dữ liệu vào tệp

*Đọc dữ liệu từ tệp:

Read(<Tên biến tệp>,<DS biến>);

Trang 10

Hoặc Readln(<Tên biến tệp>,<DS biến>);

Lưu ý: DS biến phải cùng kiểu với dữ liệu cần đọc hoặc đọc xâu hay đọc từng

kí tự

Hàm Eof(Biến tệp): có giá trị true khi đã đọc đến cuối tệp

*Ghi dữ liệu vào tệp:

Write(<Tên biến tệp>,<DS biến>);

Hoặc Writeln(<Tên biến tệp>,<DS biến>);

Đóng tệp: thao tác này bắt buộc phải có, nếu không có thể dữ liệu ttrong tệp sẽ

bị mất Khi đã đóng tệp muốn đọc hoặc ghi dữ liệu vào tệp ta cần thực hiện từ B3 (mở tệp)

4.5 Ví dụ

Ví dụ 1: Một file văn bản có tên DaySo.Dat có dạng sau:

- Dòng đầu tiên của số n chỉ số phần tử của dãy số

- Dòng tiếp theo ghi n số, mỗi số cách nhau ít nhất một khoảng trống trên mộtdòng

Viết chương trình đọc dãy số từ file lưu vào trong mảng

READLN(F,n); {doc dong dau tien vao bien n}

For i :=1 to n do readln(f,a[i]); {doc n dong sau vao cac bien a[i]}

Trang 11

Ví dụ 2: Một file văn bản ghi số liệu của một bảng số n x m và có dạng sau:

- Dòng đầu tiên của file ghi 2 số n, m cách nhau ít nhất bởi một dấu cách

- N dòng tiếp theo của file ghi số liệu của n hàng, mỗi hang bao gồm n số cáchnhau ít nhất một dấu cách

VD: File so.dat có dạng sau :

II MỘT SỐ THUẬT TOÁN

1 Tính thời gian thực hiện chương trình.

Mục đích: Đánh giá độ phức tạp của giải thuật

a Tính số lần thực hiện:

Uses windows;

Var time: longint;

Trang 12

Ta có : x.y = ( x div 2) * 2y + y nếu x lẻ

x.y = ( x div 2) * 2y nếu x chẵn

Function FastMult(x,y: longInt): LongInt;

Trang 13

3 Phép toán Mod chống tràn số (phép nhân, phép lũy thừa)

Function FastModMult(x,y,n: longInt);

While (x<>0) do Begin

If x mod 2 =1 then z:= z*a mod n; X= x div 2;

a:= a*a mod n;

End;

FastModExp:=z End;

4 Kiểm tra số nguyên dương n có là số nguyên tố hay không

Input: n nguyên dương

Bước 4: Nếu n chia hết cho i thì n không là số NT CB6

Bước 5: i:=i+1 quay lại B3

Bước 6: Kết thúc

Function KTNT(n:LongInt): Boolean;

Var kiemTra: boolean; i: LongInt;

Trang 14

kiemTra:= true;

IF n <= 1 then kiemTra:=false

Else

For i:=2 to trunc(sqrt(n) do

If n mod i =0 then Begin kiemTra:=false; Exit End;

KTNT:=kiemTra;

End

Bài tập tương tự: - Sinh số nguyên tố nhỏ nhất sau số nguyên dương n.

- Liệt kê các số nguyên tố từ 2 đến n

- Liệt kê các số nguyên tố trong các số a1, a2 … an.

6 Liệt kê các số nguyên hoàn hảo từ 1 đến n

Procedure SoHoanHao(n: Integer);

Var x,y: Integer;

Trang 15

If x mod y =0 then S:=s+i;

Bài toán cần giải quyết các bài toán con:

+ Tìm ước chung lớn nhất của 2 số a, b

+ Tìm số đảo của số x

+ Kiểm tra một số x có là sỗ tam tam không?

+ Liệt kê các số tam tam từ 100 đến 999

Function UCLN(a,b: Integer);

y := 0;

While (x<>0) do Begin y:=y*10 + x mod 10; x:= x div 10;

End SoDao=y;

End Function SoTamTam(x: Integer): Boolean;

For x:= 100 to 999 do

IF SoTamTam(x) Then write(x, ‘ ‘); End

Bài tập tương tự:

1 Số đẹp là số có tận cùng là 36 Đếm số các số đẹp nguyên dương nhỏ hơn n

2 Số nguyên tố hoàn hảo là số nguyên tố và số đảo của nó cũng là số nguyên

tố Đếm số nguyên tố hoàn hảo nhỏ hơn n

3 Một số bài tập xử lý số lớn

- Số trong pascal: single (7 chữ số); longInt( 9 chữ số); real (11 chữ số); double(15 chữ số); extended (19 chữ số), khi dùng extended phải bật chế độ {$N+}

Trang 16

- Trong Freepascal int64(19 chữ số)

Nếu số từ 10 chữ số trở lên nên dùng mảng hoặc xâu để lưu trữ

- Cách lưu trữ bằng mảng

Type SNL = array [1…max] of byte;

Bài tập 1: Cho a, b là số nguyên ( 0 a, b, k 1010) cho biết chữ số thứ k sau phầnthập phân của phép a/b

var a,b,k,t,i : extended;

function chia(var a:extended; b:extended):extended;

Trang 17

Bài tập tương tự: Cho a, b là số nguyên ( 0 a, b, k 1020) Đưa ra màn hình kết quả phép toán: a mod b, a div b.

Bài tập 2: Nhập n, sinh một số bằng cách viết liên tiếp các số từ 1 đến n Tính tổng

s:=0; i:=1;

while i<=n do begin

s:=s+tongcs(c) ; i:=i+1;

end;

writeln(s:0:0);

readln;

end.

Trang 18

Cách 2: Sử dụng xâu làm được với n <= 107, tuy nhiên tốn thời gian chuyển từ xâu sang số và chuyển từ số sang xâu.

s:=0; i:=1;

while i<=n do begin

str(i:10:0,c);

s:=s+tongcs(c) ; i:=i+1;

a[1] =45; a[2] = a[1]*10 +10*45; a[3]= a[2]*10 + 102* 45

+ Tính TongTron(k,n): tổng tất cả các chữ số của số bắt đầu bằng k có n chữ số+ Tính các chữ số được sinh ra đến n= 231

Ví dụ: TinhTong(231) = tongTron(2,3)+ 2* 32 + TinhTong(31)

TinhTong(31)= tongTron(3,2) + 3*3 +TinhTong(1)

while(S<>'') do begin

Trang 19

- Cần biết i ở bít thứ mấy: (i-1) mod 8

- Cần biết i ở byte thứ mấy: i div 8 +1

- Để tăng tốc độ tính toán nên sử dụng phép dịch bít

a mod 2n  a and (2n-1)

a div 2n  a shr n

- Nhận giá trị của bit thứ i của x : if (x and (1 shl i) =0 then gt:=0 else gt =1

- Đặt bit i của x giá trị 0 hoặc 1: Đặt 0: x:= x and(not (1 shl i))

a^[ (i -1) div 8+1]:= a^[(i-1) div 8+1] or (1 shl (7- ((i-1) mod 8))); {bat bit}

for i:=1 to 10 do a^[i]:=255;

i:=2;

Trang 20

a^[ (i -1) div 8+1]:= a^[(i-1) div 8+1] and not(1 shl (7- ((i-1) mod 8))); {tat bit}

for i:=1 to 10 do writeln(a^[i]);

Bài tập 3: Một tệp văn bản chứa các số từ 1 đến 1000000, hãy loại bỏ các số trùng

nhau và sắp xếp lại tệp tăng dần

Hướng dẫn:

- Đọc các số lưu vào 1 mảng byte với số phần tử 1000000/8

- Đọc giá trị x đánh dấu mảng tại vị tri bít thứ x bằng 1;

- Ghi mảng vào tệp như sau: Nếu tại bit thứ x bằng 1 thì ghi x

5 Thuật toán sắp xếp nhanh

x=a[r] ;con t=true;

while (r *2<=e) and cont do Begin

j=r*2;

if (j <e ) then

if a[j] < a[j+1] then j=j+1;

if x >= a[j] then cont=false else

Begin a[r]=a[j]; r=j; End; End;

a[r]=x;

End;

Begin for r=(n div 2) downto 1 do sift(r,n); for r=n downto 2 do

Begin Doi_cho(a[1],a[r]); sift(1,r-1); End

Trang 21

End;

III TÌM KIẾM LỜI GIẢI

1 Mô hình hóa bài toán

T: Tập các trạng thái của bài toán  Các đỉnh đồ thị

F: Tập các toán tử chuyển trạng thái  Cạnh, cung của đồ thị

2 Mô tả dữ liệu cho bài toán

Cần lưu trữ T hiệu quả, S,G là tập con của T

F: Thường viết thành 1 hàm xây dựng trạng thái mới từ trạng thái cũ Cần lựa chọn một dạng mô tả nào đó của các trạng thái

T: Thường được sử dụng kiểu tập hợp

Thông thường các giải thuật tìm kiếm đều yêu cầu đánh dấu các trạng thái đã điqua để tránh lặp lại do vậy việc đánh dấu nên dùng BitSet khi không gian trạng tháinhỏ, khi không gian trạng thái quá lớn nên dùng cây tìm kiểm nhị phân để tìm kiếmcho nhanh Nếu cần lưu trữ để lấy kết quả thì dùng mảng Truoc[u] = v để lưu trữtrạng thái trước trạng thái u

Ví dụ:

1 Bảng số: Một bảng số có n dòng m cột mỗi ô lưu một số nguyên dương Tìm cách đi từ ô (x,y) đến ô (x1, y1) theo một cách thức cho trước

+ Mô hình hóa bài toán

Không gian trạng thái lưu trữ bằng mảng 2 chiều

Trạng thái các ô: (x,y)

Trạng thái của ô:

Type Dinh = recordx,y: longint;

End;

Cần mảng lưu trọng số c[u] = c[u.x,u.y] = giá trị tại ô (x,y)

Ngày đăng: 21/01/2016, 09:44

TỪ KHÓA LIÊN QUAN

w