1. Trang chủ
  2. » Kỹ Thuật - Công Nghệ

PHÁT TRIỂN KỸ NĂNG GIẢI BÀI TOÁN Bằng TIN HỌC

35 90 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 35
Dung lượng 1,24 MB

Nội dung

I. Giải bài toán Tin Phần này sẽ giới thiệu một số bước thường vận dụng trong quá trình giải các bài toán Tin. 1. Bước đầu tiên và là bước quan trọng nhất là hiểu rõ nội dung bài toán. Đây là yêu cầu quen thuộc đối với những người làm toán. Để hiểu bài toán theo cách tiếp cận của tin học ta phải gắng xây dựng một số thí dụ phản ánh đúng các yêu cầu đề ra của đầu bài rồi thử giải các thí dụ đó để hình thành dần những hướng đi của thuật toán. 2. Bước thứ hai là dùng một ngôn ngữ quen thuộc, tốt nhất là ngôn ngữ toán học đặc tả các đối tượng cần xử lí ở mức độ trừu tượng, lập các tương quan, xây dựng các hệ thức thể hiện các quan hệ giữa các đại lượng cần xử lí. 3. Bước thứ ba là xác định cấu trúc dữ liệu để biểu diễn các đối tượng cần xử lí cho phù hợp với các thao tác của thuật toán. Trong những bước tiếp theo ta tiếp tục làm mịn dần các đặc tả theo trình tự từ trên xuống, từ trừu tượng đến cụ thể, từ đại thể đến chi tiết. 4. Bước cuối cùng là sử dụng ngôn ngữ lập trình đã chọn để viết chương trình hoàn chỉnh. Ở bước này ta tiến hành theo kĩ thuật đi từ dưới lên, từ những thao tác nhỏ đến các thao tác tổ hợp. Sau khi nhận được chương trình ta cho chương trình chạy thử với các dữ liệu lấy từ các thí dụ đã xây dựng ở bước đầu tiên. Điều quan trọng là xây dựng các thủ tục một cách khoa học và có chủ đích nhằm kiểm tra tính tin cậy của chương trình thu được và thực hiện một số cải tiến. Chúng ta sẽ vận dụng cách tiếp cận trên để giải một số bài toán cụ thể. Những phần trình bày dưới đây có thể sử dụng một vài kí pháp quen thuộc của tin học, thí dụ: x = abc số tự nhiên x được tạo bởi ba chữ số a, b và c. a, b = 0..9 hai số a và b có thể nhận các giá trị từ 0 đến 9. Sở dĩ ta không sử dụng các kí hiệu toán học vì trên bàn phím máy tính không có các kí hiệu đó. Chọn các kí hiệu có sẵn trong các ngôn ngữ lập trình giúp chúng ta có thể viết các chú thích ngay trong chương trình. Bài 1.1. Số thân thiện Tìm tất cả các số tự nhiên có hai chữ số mà khi đảo trật tự của hai chữ số đó sẽ thu được một số nguyên tố cùng nhau với số đã cho. Hiểu đầu bài Ta kí hiệu (a, b) là ước chung lớn nhất (ucln) của hai số tự nhiên a và b. Hai số tự nhiên a và b được gọi là nguyên tố cùng nhau khi và chỉ khi (a, b) = 1. Khi đó, chẳng hạn: a. (23, 32) = 1, vậy 23 là một số cần tìm. Theo tính chất đối xứng, ta có ngay 32 cũng là một số cần tìm. b. (12, 21) = 3, vậy 12 và đồng thời 21 không phải là những số cần tìm. Đặc tả: Gọi hai chữ số của số tự nhiên cần tìm x là a và b, ta có: (1) x = ab. (2) a, b = 0..9 (a và b biến thiên trong khoảng 0..9). (3) a > 0 vì x là số có hai chữ số. (4) (ab, ba) = 1. Ta kí hiệu x là số đối xứng của số x theo nghĩa của đầu bài, khi đó ta có đặc tả như sau: (5) x = 10..99 (x biến thiên từ 10 đến 99, vì x là số có hai chữ số). (6) (x, x) = 1. Nếu x = ab thì x = ba. Ta có thể tính giá trị của x theo công thức: x = (chữ số hàng đơn vị của x) 10 + (chữ số hàng chục của x). Kí hiệu Đơn(x) là toán tử lấy chữ số hàng đơn vị của số tự nhiên x và kí hiệu Chục(x) là toán tử lấy chữ số hàng chục của x, ta có:

TRƯỜNG ĐHSP HUẾ KHOA TIN HỌC PHÁT TRIỂN KỸ NĂNG GIẢI BÀI TOÁN TIN HỌC Nguyễn Đức Nhuận Huế, 5/2009 I Giải toán Tin Phần giới thiệu số bước thường vận dụng trình giải toán Tin Bước bước quan trọng hiểu rõ nội dung toán Đây yêu cầu quen thuộc người làm toán Để hiểu toán theo cách tiếp cận tin học ta phải gắng xây dựng số thí dụ phản ánh yêu cầu đề đầu thử giải thí dụ để hình thành dần hướng thuật tốn Bước thứ hai dùng ngơn ngữ quen thuộc, tốt ngơn ngữ tốn học đặc tả đối tượng cần xử lí mức độ trừu tượng, lập tương quan, xây dựng hệ thức thể quan hệ đại lượng cần xử lí Bước thứ ba xác định cấu trúc liệu để biểu diễn đối tượng cần xử lí cho phù hợp với thao tác thuật toán Trong bước ta tiếp tục làm mịn dần đặc tả theo trình tự từ xuống, từ trừu tượng đến cụ thể, từ đại thể đến chi tiết Bước cuối sử dụng ngơn ngữ lập trình chọn để viết chương trình hồn chỉnh Ở bước ta tiến hành theo kĩ thuật từ lên, từ thao tác nhỏ đến thao tác tổ hợp Sau nhận chương trình ta cho chương trình chạy thử với liệu lấy từ thí dụ xây dựng bước Điều quan trọng xây dựng thủ tục cách khoa học có chủ đích nhằm kiểm tra tính tin cậy chương trình thu thực số cải tiến Chúng ta vận dụng cách tiếp cận để giải số toán cụ thể Những phần trình bày sử dụng vài kí pháp quen thuộc tin học, thí dụ: x = abc số tự nhiên x tạo ba chữ số a, b c a, b = hai số a b nhận giá trị từ đến Sở dĩ ta khơng sử dụng kí hiệu tốn học bàn phím máy tính khơng có kí hiệu Chọn kí hiệu có sẵn ngơn ngữ lập trình giúp viết thích chương trình Bài 1.1 Số thân thiện Tìm tất số tự nhiên có hai chữ số mà đảo trật tự hai chữ số thu số nguyên tố với số cho Hiểu đầu Ta kí hiệu (a, b) ước chung lớn (ucln) hai số tự nhiên a b Hai số tự nhiên a b gọi nguyên tố (a, b) = Khi đó, chẳng hạn: a (23, 32) = 1, 23 số cần tìm Theo tính chất đối xứng, ta có 32 số cần tìm b (12, 21) = 3, 12 đồng thời 21 khơng phải số cần tìm Đặc tả: Gọi hai chữ số số tự nhiên cần tìm x a b, ta có: (1) x = ab (2) a, b = (a b biến thiên khoảng 9) (3) a > x số có hai chữ số (4) (ab, ba) = Ta kí hiệu x' số đối xứng số x theo nghĩa đầu bài, ta có đặc tả sau: (5) x = 10 99 (x biến thiên từ 10 đến 99, x số có hai chữ số) (6) (x, x') = Nếu x = ab x' = ba Ta tính giá trị x' theo cơng thức: x' = (chữ số hàng đơn vị x) * 10 + (chữ số hàng chục x) Kí hiệu Đơn(x) toán tử lấy chữ số hàng đơn vị số tự nhiên x kí hiệu Chục(x) toán tử lấy chữ số hàng chục x, ta có: x' = Đơn(x)*10 + Chục(x) Tổng hợp lại ta có đặc tả: Số cần tìm x phải thoả tính chất sau:x = 10 99 (x nằm khoảng từ 10 đến 99) (7) x' = Đơn(x)*10 + Chục(x) (8) (x, x') = (ước chung lớn x x' 1) Đặc tả thể qua ngôn ngữ tựa Pascal sau: (9) for x:=10 to 99 if ucln(x, đơn(x)*10+Chục(x))=1 then Lấy(x); đó, ucln(a,b)là hàm cho ước chung lớn hai số tự nhiên a b; Lấy(x) toán tử hiển thị x lên hình ghi x vào mảng với mục đích sử dụng lại, cần Ta làm mịn đặc tả (10): ucln(a, b): Thuật toán Euclid chia liên tiếp, thay số thứ dư chia cho số thứ hai hoán vị hai số (* Tim uoc chung lon nhat cua hai so a va b Thuat toan Euclid *) function Ucln(a,b: integer): integer; Var r:integer; begin while b > begin r:= a mod b; a:= b; b:= r; end; Ucln:= a; end; Đơn(x) = (x mod 10): số dư phép chia nguyên x cho 10, thí dụ: Đơn(19) = 19 mod 10 = Chục(x) = (x div 10): thương nguyên phép chia x cho 10, thí dụ: Chục(19) = 19 div 10 = Lấy(x): write(x) nạp giá trị x vào mảng s theo thao tác sau: n := n + 1; s[n] := x; n đếm số phần tử nạp mảng s Biểu diễn liệu Ta dùng mảng s để lưu số tìm Dễ thấy s phải mảng nguyên chứa tối đa 90 phần tử số cần khảo sát nằm khoảng từ 10 đến 99 var s: array[1 90] of integer; Phương án chương trình hoạt động theo hai bước sau: n := Tim; Xem(n); Bước Tìm ghi vào mảng s số thoả điều kiện đầu bài, n số lượng số tìm Bước Hiển thị phần tử mảng s[1 n] chứa số tìm Tốn tử x' viết dạng hàm cho ta số tạo chữ số x theo trật tự ngược lại Ta đặt tên cho hàm SoDao (số đảo) Hàm nhận giá trị vào số tự nhiên có nhiều chữ số Để tạo số đảo y số x cho trước, hàm SoDao lấy dần chữ số hàng đơn vị x để ghép vào bên phải số y: y := y*10 + (x mod 10) Sau bước, chữ số hàng đơn vị lấy loại hẳn khỏi x toán tử: x := x div 10 Chỉ thị {$B-} chương trunh NTCN (nguyên tố nhau) đặt chế độ kiểm tra biểu thức lôgic vừa đủ Khi xác định giá trị chân lí cần thiết khơng tiến hành tính tiếp giá trị biểu thức Thí dụ, với lệnh x := 1; y := 5; if (x > 5) and (x + y < 7)then y := y + else y := y-1; chế độ {$B-}, sau tính giá trị chân lí (x > 5) = false, chương trình bỏ qua nhân tử logic (x + y < 7), tích lơgic false với giá trị tuỳ ý cho ta false Trong trường hợp lệnh y := y - thực Ngược lại, ta đặt thị {$B+} chương trình, sau tính (x > 5) = false tiếp tục tính giá trị (x + y < 7) lấy tích hai giá trị tìm (false and true = false) làm giá trị biểu thức điều kiện cấu trúc rẽ nhánh nói Cuối tốn tử y:= y thực giống trường hợp khối lượng tính tốn lại nhiều (* -So than thien (xy,yx) = *) program SoThanThien; {$B-} uses Crt; const MN = 90; var s: array[1 MN] of integer; function Ucln(a,b: integer): integer; tự viết function SoDao(x: integer): integer; var y: integer; begin y := 0; repeat { ghep chu so hang don cua x vao ben phai y } y := 10*y + (x mod 10); x := x div 10; { loai chu so hang don } until (x = 0); SoDao := y; end; (* -Tim cac so thoa dieu kien dau bai ghi vao mang s Output: so luong cac so tim duoc *) function Tim: integer; var x,d: integer; begin d := 0; {So luong cac so can tim } for x := 10 to 99 if Ucln(x,SoDao(x)) = then begin d := d + 1; s[d]:= x; end; Tim := d; end; (* -Hien thi mang s[1 n] tren man hinh *) procedure Xem(n: integer); var i: integer; begin writeln; for i := to n write(s[i]:4); writeln; end; BEGIN n := Tim; Xem(n); writeln; write(' Tong cong ',n,' so'); readln; END Cải tiến Ta vận dụng tính đối xứng nhận xét phần để cải tiến chương trình Như cần khảo sát số x = ab, với a > b ≥ Trường hợp a = b ta không xét x' = x Ucln(x, x) = x ≥ 10 ≠ Nếu b = ta có x = 10a x' = a Ta thấy Ucln(10a, a)= a = a = Do ta xét riêng trường hợp Khi ab = 10 ta có (10, 1) = Vậy 10 số cần tìm số Mỗi tìm hai chữ số a b thoả điều kiện a >b Ucln(a*10+b, b*10+ a) =1 ta đưa a*10 + b vào kết quả, b > ta đưa thêm số đảo b*10 + a vào kết (* So Than thien: Phuong an -*) function Tim2: integer; var a,b,d: integer; begin d:= 1; {So luong cac so can tim} s[d] :=10; for a := to for b := to a-1 if Ucln(a*10+b,b*10+a)=1 then begin d := d + 1; s[d] := a*10 + b; d := d + 1; s[d] := b*10 + a; end; Tim2:=d; end; Bài 1.2 Số cấp cộng Tìm số tự nhiên lẻ có ba chữ số Ba chữ số này, theo trật tự từ trái qua phải tạo thành cấp số cộng Đặc tả x số tự nhiên có ba chữ số: x = 100*a + 10*b + c x số lẻ nên chữ số hàng đơn vị c phải số lẻ: c = 1, 3, 5, 7, Chữ số hàng trăm x phải khác 0: a = Nếu dãy a, b, c lập thành cấp số cộng số đứng b trung bình cộng hai số đầu cuối: b = (a + c)/2 hay 2b = a+c Từ (4) ta suy (a + c) số chẵn Do c lẻ, (a + c) chẵn nên a lẻ Nếu biết a c ta tính x = 100a +10(a + c) / + c = 100a + 5(a + c) + c = 105a + 6c Vì có chữ số lẻ 1, 3, 5, nên tổ hợp a c cho ta 25 số Tổ chức liệu Ta tạo sẵn mảng nguyên phần tử ChuSoLe[1 5] gán trước giá trị 1, 3, 5, 7, cho mảng Trong Turbo Pascal (TP) việc thực thông qua khai báo: const ChuSoLe: array[1 5] of integer = (1,3,5,7,9); Chú ý khai báo phải đặt mục const nơi khai báo Ý nghĩa dòng khai báo sau: Xin cấp phát biến mảng kiểu nguyên có phần tử với dẫn từ đến 5, tên biến ChuSoLe phần tử biến gán trước trị 1, 3, 5, Sau đó, cần, ta việc duyệt mảng ChuSoLe thu toàn chữ số lẻ theo trật tự khai báo trước Chú ý Thủ tục inc(d) chương trình TP tăng giá trị biến d lên thêm đơn vị, tức tương đương với câu lệnh d:=d+1;Tương tự, thủ tục dec(d) giảm giá trị biến d xuống đơn vị, tương đương với câu lệnh d:= d – 1; Tổng quát hơn, ta viết: inc(d,n) tương đương với d := d + n dec(d,n) tương đương với d := d - n Khi n = bỏ qua tham số thứ hai ( Cac so tu nhien le chu so lap cap so cong -*) program CapCong; uses crt; const ChuSoLe: array [1 5] of integer = (1,3,5,7,9); var s: array [1 25] of integer; n: integer; (* Phat sinh cac so dang 105a+6c; a,c = 1,3,5,7,9 *) Function Tim: integer; var a,c,d,x: integer; begin d := 0; for a := to begin x := 105*ChuSoLe[a]; for c := to begin inc(d); s[d] := x + 6*ChuSoLe[c]; end; end; Tim := d; end; (* Hien thi mang s[1 n] moi dong 20 so -*) procedure Xem(n: integer); tự viết BEGIN n := Tim; Xem(n); writeln; write('Tong cong ',n,' so'); readln; END Chú ý: Dựa vào nhận xét: dãy ba số a, b, c tạo thành cấp số cộng b trung bình cộng a c, tức 2b = a + c ta giải tốn phương pháp vét cạn dùng ba vòng for sau: for a := to for b := to for c := to if odd(c) and (2*b=a+c) then Ghi nhận số 100*a+10*b+c; Hàm odd(c) kiểm tra tính lẻ số nguyên c Phương pháp vét cạn đòi hỏi khoảng 10*10*10 = 1000 lần duyệt có 25 số, tức phần bốn mươi số thoả mãn điều kiện đầu Phương pháp mơ tả chương trình gọi phương pháp sinh: sinh 25 số cần tìm Ta cần ghi nhận phương pháp sinh Phương pháp sinh: Thay duyệt tìm đối tượng sinh chúng Bài 1.3 Số cấp nhân Tìm số tự nhiên có ba chữ số Ba chữ số này, theo trật tự từ trái qua phải tạo thành cấp số nhân với công bội số tự nhiên khác Đặc tả Chú ý ta xét cấp số dãy số tự nhiên với công bội d số ngun dương Gọi x số cần tìm, ta có: x số có ba chữ số: x = 100*a + 10*b + c a = 9; b = a*d; < c = a*d*d ≤ Hệ thức cho phép ta tính giới hạn d: ad ≤ d≤ √ Vì d số nguyên nên ta phải có d ≤ trunc(sqrt(9 div a)), sqrt hàm tính bậc hai, trunc hàm lấy phần nguyên Ta cho a biến thiên khoảng cho công bội d biến thiên khoảng từ đến trunc(sqrt(9 div a)) Với cặp số a d ta tính x = 100*a+10*a*d+a*d*d = a*(100+10*d+d*d) Tuy nhiên, ta nhẩm tính trước cận d đỡ phải gọi hàm trunc sqrt hàm thao tác số thực tốn thời gian a Cận d 1 1 1 (* -Cac so tu nhien chu so lap cap nhan *) program CapNhan; uses crt; const MN = 30; cd: array[1 9] = (3,2,1,1,1,1,1,1,1); var s: array [1 MN] of integer; n: integer; function Tim: integer; var a,d,n: integer; begin n:= 0; for a:= to for d:=1 to cd[a]do begin inc(n); s[n]:= a*(100+10*d+d*d); end; Tim:= n; end; procedure Xem(n: integer): tự viết BEGIN clrscr; n:= Tim; Xem(n); writeln; write('Tong cong ',n,' so'); readln; END Bài 1.4 Mảng ngẫu nhiên Sinh ngẫu nhiên n số nguyên không âm cho mảng nguyên a Đặc tả Trong TP hàm random(n) sinh số ngẫu nhiên kiểu nguyên nằm khoảng từ đến n - Hãy tưởng tượng có quân súc sắc n mặt mã số mặt từ đến n -1 Khi ta gọi hàm random(n) máy tính gieo qn súc sắc cho ta giá trị xuất mặt ngửa Chú ý Trước gọi hàm random ta cần gọi thủ tục randomize để máy tính khởi động chế phát sinh số ngẫu nhiên Thủ tục Gen(m) chương trình sinh ngẫu nhiên m số nguyên khoảng từ đến m - Ta cải tiến để viết thủ tục Gen(n,d,c)sinh ngẫu nhiên n số nguyên khoảng từ d đến c (d < c) Để ý random(c-d+1) biến thiên khoảng từ đến c-d, d+random(c-d+1) biến thiên khoảng từ d đến d+c-d = c program RandomGen; (* -Sinh ngau nhien n so nguyen khong am cho mang a - *) {$B-} uses crt; const MN = 500; var a: array [1 MN] of integer; n: integer; Procedure Gen(m: integer); var i: integer; begin randomize; n := m; for i := to n a[i] := random(m); end; procedure Xem: tự viết; BEGIN Gen(200); Xem; END Bài 1.5 Chia mảng tỉ lệ 1:1 Tìm cách chia dãy số ngun khơng âm a1, a2, ,an, n > cho trước thành hai đoạn có tổng phần tử đoạn Đặc tả Ta quy ước viết #E "tồn tại" #V "với mọi" Kí hiệu sum(a[d c]) tổng phần tử liên tiếp từ a[d] đến a[c] dãy a: sum(a[d c]) = a[d] + a[d +1]+ + a[c] Gọi t tổng phần tử mảng: t = sum(a[1 n]) Muốn chia a thành hai đoạn a[1 i] a[i+1 n] có tổng ta phải có: t số chẵn (t chia hết cho 2) Đặt t2 = t div 2 (#E i: t2 then exit; {vo nghiem } if tr = t2 then { co nghiem i } begin Chia:= i; exit; end; end; end; procedure Test; var i: integer; begin repeat Gen(10); Xem; i := Chia; if i = -1 then writeln('Khong chia duoc') else begin writeln('Doan thu nhat: a[1 ',i,']'); writeln('Doan thu hai: a[',i+1,' ',n,']'); end; until ReadKey=Esc; end; BEGIN Test; END Chú ý Muốn dừng chương trunh nhấn phím Esc có mã ASCII #27 Nếu mảng a có chứa số giá trị tốn có nhiều nghiệm (nhiều cách chia) Bài 1.6 Chia mảng tỉ lệ 1:k Tìm cách chia dãy số ngun khơng âm a1, a2, ,an, n > cho trước thành hai đoạn có tổng phần tử đoạn gấp k lần tổng phần tử đoạn kia, k nguyên dương Đặc tả Gọi t tổng phần tử dãy a, t = sum(a[1 n]) Muốn chia a thành hai đoạn a[1 i] a[i + n] có tổng gấp k lần ta phải có: t chia hết cho (k + 1) Đặt t1 = t div (k + 1) tk = t - t1 (#E i: t1 ta chưa thể kết luận tốn vơ nghiệm Trường hợp ta phải tiếp tục tích luỹ tr để hi vọng đạt tổng tr = tk Nếu sau tích luỹ ta thu tr = tk tốn có nghiệm i, ngược lại, tr > tk ta kết luận tốn vơ nghiệm Function Chia(n,k: integer): integer; var i: integer; t, t1, tk, tr: longint; begin Chia := -1; t := 0; { t = sum(a[1 n]) } for i := to n t := t+a[i]; 10 + i:=i+1; + While a[i+1]=a[i] i:=i+1; Đáp số : a[i+1] Một số tập tự giải Bài 2.12 Viết chương trình nhập vào dãy số ngun có n phần tử a Đưa phần tử lẻ đầu danh sách, phần tử chẵn cuối danh sách in kết hình b Sắp xếp phần tử lẻ đầu danh sách theo thứ tứ tăng dần, xếp phần tử chẵn cuối danh sách theo thứ tự giảm dần In danh sách hình Bài 2.13 Viết chương trình nhập vào từ bàn phím mảng A gồm N phần tử số nguyên gồm loại số : Loại : số vừa chia hết cho vừa lẻ, loại : số vừa chia hết cho vừa chẵn, loại : số lại Yêu cầu xếp số loại lên đầu dãy , số loại xuống cuối dãy , số loại dãy Trước hết xếp gọn hết số loại , sau xếp đồng thời số loại Đưa hình dãy xếp Dữ liệu vào Dữ liệu N=8 88 29 81 12 42 35 62 83 88 29 81 12 42 35 62 83 81 29 88 62 83 35 12 42 Bài 2.14 Viết chương trình nhập vào từ bàn phím mảng chiều A gồm M phần tử, mảng chiều B gồm N phần tử, xếp dãy A B tăng dần sau trộn dãy thành dãy C cho dãy C dãy xếp tăng dần In mảng A, B, C hình Bài 2.15 Nhập vào mảng số nguyên a/ Xếp lại mảng theo thứ tự giảm dần b/ Nhập vào số nguyên từ bàn phím Chèn số vào mảng cho mảng có thứ tự giảm dần (không xếp lại mảng) Bài 2.16 Nhập mảng gồm N số nguyên từ bàn phím Sau nhập số nguyên X Hãy loại bỏ dãy phần tử X In dãy hình VD : Dãy: 6 với X = => Dãy in ra: Bài 2.17 Đoạn không giảm dài Cho dãy gồm N số nguyên Tìm đoạn khơng giảm có chiều dài lớn MDOAN.INP 12 5 3 MDOAN.OUT Dữ liệu vào: tệp văn MDOAN.INP Dòng thứ nhất: số tự nhiên N, ≤ N ≤ 20000 Từ dòng thứ hai trở đi: phần tử dãy Dữ liệu ra: tệp văn MDOAN.OUT Chứa dòng gồm hai số tự nhiên d số đầu đoạn L - số phần tử đoạn (chiều dài đoạn) Trong tệp, liệu dòng cách qua dấu cách Thí dụ cho ta đoạn khơng giảm dài bao gồm phần tử phần tử 21 thứ tư dãy (các phần tử gạch dưới): 5 3 Bài 2.18 Trả tiền Có N loại tiền mệnh giá mi số lượng si , i = N Xác định số lượng loại để trả lại V đồng TRATIEN.INP 156 10 20 50 TRATIEN.OU T 0 Dữ liệu vào: tệp văn TRATIEN.INP Dòng đầu tiên: hai số tự nhiên N V, ≤ N ≤ 15 Dòng thứ hai: N số tự nhiên m1, m2,…,mN Dòng thứ ba: N số tự nhiên s1, s2,…,sN Dữ liệu ra: tệp văn TRATIEN.OUT N số tự nhiên c1, c2,…,cN thể số lượng tờ tiền loại cần trả, c1m1 + c2m2 + …+ cNmN = V Nếu vô nghiệm: ghi số Bài 2.19 Số Kapreka Số Kapreka mang tên nhà toán học Ấn Độ mơ tả sau Đó số tự nhiên x viết hệ đếm B có K chữ số khác đôi x = x‟‟ - x‟, x‟‟ x‟ số thu cách lại chữ số số x theo trật tự giảm tăng dần Với cặp giá trị B K tìm số Kapreka KAPREKA.INP 10 KAPREKA.OUT 6174 Dữ liệu vào: tệp văn KAPREKA.INP Dòng đầu tiên: hai số B K cách qua dấu cách, ≤ B ≤ 10, K < B Dữ liệu ra: tệp văn KAPREKA.OUT Số x viết hệ đếm B Bộ liệu cho biết: Trong hệ đếm thập phân (B = 10), x = 6174 số Kapreka có chữ số (khác đơi một), x'' - x' = 7641 = 1467 = 6174 = x Nhóm tốn xử lý xâu Để giải toán xâu cần cho học sinh nắm vững hàm, thủ tục xử lý xâu hàm COPY(), LENGTH(), INSERT(), STR() , VAL()… Dạng Xử lý số nguyên lớn Phương pháp chung: Để thực phép tính xử lý với số ngun ngồi phạm vi biểu diễn cung cấp, cách đơn giản sử dụng xâu kí tự để biểu diễn với ký tự xâu tương ứng với chữ số số nguyên lớn tính từ trái qua phải Dưới xin đưa số ứng dụng kiểu xâu xử lý số lớn Bài 2.20 Cộng, trừ số nguyên lớn Cho hai số ngun dương lớn có có độ dài khơng q 200 chữ số Hãy đưa tổng hiệu số nguyên * Ý tưởng: Sử dụng xâu để lưu số lớn Trước hết cho xâu cách chèn thêm nhiều ký tự '0' vào trước xâu ngắn Việc thực cộng số 22 thực cách cộng cặp ký tự số tương ứng từ phải sang trái xâu (Đối với phép trừ số nguyên thực tương tự) * Đoạn chương trình: function var Add(s1,s2:string):string; i,nho,z,x,y:longint; s:string; begin while length(s1)=s2 then sub:=sub1(s1,s2) else sub:='-'+sub1(s2,s1); end; Bài 2.21 Ghép số lớn Vaxia viết số lớn cuộn giấy dài muốn khoe với anh trai Petia thành vừa đạt Tuy nhiên, Vaxia vừa khỏi phòng để gọi anh trai em Kachia chạy vào phòng xé rách cuộn giấy thành số mảnh Kết mảnh có vài kí số theo thứ tự viết Bây Vaxia khơng thể nhớ xác viết số Vaxia nhớ số lớn Để làm hài lòng cậu em trai, Petia định truy tìm số lớn mà Vaxia viết lên cuộn giây trước bị xé Bạn giúp Petia làm việc Dữ liệu vào: Ghi nhiều dòng Mỗi dòng ghi dãy kí số Số dòng khơng vượt q 100 Mỗi dòng ghi từ đến 100 kí số Bảo đảm có dòng mà kí số khác Dữ liệu ra: Ghi số lớn viết cuộn giấy trước bị xé rách Ví dụ Input 20 004 66 Output 66220004 24 * Ý tưởng: Lưu số dạng mảng kiểu xâu, thực xếp mảng theo thứ tự tăng dần theo tiêu chí xếp phần tử s[i] đứng trước phần từ s[j] (s[i] ghép với s[j]) > (s[j] ghép với s[i]) * Chương trình tham khảo var s: array[0 1000] of string; i,n,j: word; {===================} procedure qsort(L,H: word); var tg,k:string; begin if l>=h then exit; i:=l; j:=h; tg:=s[(l+h) div 2]; repeat while tg+s[i]s[j]+tg dec(j); if ilength(s); for i:=1 to 26 begin k:=i; for j:=i to length(s)+i-5 if s[k]i then delete(s,i,k-i); end; writeln(copy(s,1,5)); end; {===========================} Begin Nhap; xuly; readln; end Bài 2.23 Số nhỏ Một số nguyên dương n lớn cho P (P 20) số nguyên dương A P xâu ký tự s1, s2, ,sp (độ dài xâu không vượt 255) gồm số thập phân cách viết s1 liên tiếp A1 lần viết s2 liên tiếp A2 lần, , viết sp liên tiếp Ap lần Giả sử với số n cho cho trước số nguyên dương k nhỏ số chữ số N Hãy tìm cách gạch k chữ số N để nhận số có giá trị nhỏ Ví dụ: Vào Kết p=3, k =11 44 a1=3, a2 = 4, a3 = s1 = 123, s2=0, s3 = 45 * Ý tưởng: Ở toán N số nguyên lớn nên ta sử dụng xâu để biểu diễn nó, giả sử số n lớn ghép lại m ký tự khác sau xóa ta lại m-k chữ số n Lần lượt tìm m chữ số nhỏ xâu lại ta kết cần tìm Dạng Biến đổi xâu Phương pháp chung: Đây dạng thường gặp, việc biến đổi xâu thực ký tự xâu nên cần nắm rõ hàm, thủ tục kiểu liệu xâu để vân dụng cách linh hoạt vào tập cụ thể Bài 2.24 Rút gọn xâu 27 Cho xâu S gồm chữ in thường với độ dài tối đa 250 ký tự Em viết chương trình để tạo xâu SG từ xâu S cách xóa ký tự liên tiếp giống xâu S để lại kí tự đại diện đoạn Dữ liệu vào: Đọc từ file văn XAUGON.INP chứa xâu S gồm chữ in thường Kết quả: Ghi file văn XAUGON.OUT xâu SG tìm Ví dụ: XAUGON.INP XAUGON.OUT Hhooocccsssiiiiinnnhhh Hocsinh * Ý tưởng: Duyệt từ đầu xâu đến cuối xâu, gặp ký tự liên tiếp giống xóa ký tự Bài 2.25 Nén giải nén Một xâu kí tự "nén" theo cách sau: Một xâu gồm n>1 kí tự giống nhau, chẳng hạn gồm n kí tự "a" ghi thành na Ví dụ xâu 'aaaabbcd' nén thành 4a2bcd Hãy viết chương trình nén giải nén (Chú ý xâu nén phải khơng có chữ số) Dữ liệu vào: Cho tệp string.INP Kết quả: Ghi vào tệp String.Out string.inp string.out Aaaabbcd 4a2bcd 3a2b aaabb * Ý tưởng: Với việc nén xâu ta đếm ký tự giống liên tiếp xâu sử dụng xâu kq để lưu kết tìm xét hết xâu (việc giải nén thực ngược lại) Bài 2.26 Ký tự khác Cho xâu s (có độ dài không vượt 106) gồm ký tự từ 'a' đến 'z' Cho biết có loại ký tự xuất s đưa ký tự xuất nhiều s với số lần xuất ký tự * Ý tưởng: - Với xâu có độ dài tối đa 106 ta sử dụng khai báo kiểu xâu Ansistring - Sử dụng mảng đánh dấu B['a' 'z'] of longint để đếm số lần xuất ký tự xâu s với B[ch] = d có nghĩa ký tự ch xuất d lần 28 - Lần theo giá trị mảng B ta số lượng ký tự khác (tức số lượng phần tử có giá trị khác khơng mảng B) tìm giá trị lớn mảng B ta tìm ký tự xuất nhiều lần Bài 2.27 Gửi thư Vị Giám đốc công ty XYZ cần gửi văn quan trọng tới đối tác Văn xâu S chữ la tinh in thường Để bảo mật nội dung văn bản, ông Giám đốc gửi thư Bức thư thứ phần đầu Sb xâu S, thư thứ phần cuối Se S Hai thư Sb Se đảm bảo đầy đủ nội dung S, nhiên phần cuối Sb viết lặp lại phần đầu Se, song số kí tự viết lặp lại khơng biết trước Ví dụ: với văn S=’truongnguyenduquannhat’ tạo hai thư: Sb=’truongnguyendu’ Se=’nguyenduquannhat’ Yêu cầu: Cho hai xâu Sb Se, xác định xâu S nội dung thư cho độ dài xâu S ngắn ữ iệu Dòng đầu chứa xâu Sb, dòng thứ hai chứa xâu Se Mỗi xâu có độ dài khơng q 250 ết Ghi độ dài xâu S tìm Ví dụ Dữ liệu truongnguyendu nguyenduquannhat Kết 22 * Ý tưởng: - Lần lượt xét xâu d, c tương ứng tính từ cuối xâu s1 đầu xâu s2, d=c ta lưu lại độ dài xâu d Quá trình tiếp tục ta nhận độ dài xâu chung dài cần tìm (giả sử max) Dạng Các tập xâu Palindrome Phương pháp chung: Xâu Palindrome hay gọi xâu đối xứng, có nghĩa xâu đọc ký tự xâu từ trái sang phải giống từ phải sang trái xâu gọi xâu Palinhdrome Với tập kiểm tra xâu Palindrome hay tìm kiếm xâu có tính chất Palindrome trước hết nên xây dựng hàm kiểm tra tính chất đối xứng xâu với độ phức tạp O(n), sở giải tập khó Bài 2.28 Xâu Palindrome Cho xâu S có độ dài khơng vượt q 106 Kiểm tra xem xâu S có phải xâu Palindrome hay không? 29 * Ý tưởng: Một xâu s có tính chất đối xứng s[i] = s[n-i+1] với i chạy từ đến length(s) div Dựa sở ta xây dựng hàm kiểm tra Bài 2.29 Xâu Palindrome Cho xâu S có độ dài khơng vượt q 1000 kí tự; tìm xâu palindrome dài xâu S * Ý tưởng: Sử dụng phương pháp quy hoạch động cách sử dụng mảng chiều F giá trị F[i, j] = true/false đoạn gồm kí tự từ i đến j S có/khơng palindrome Ta có công thức là: - F[i, i] = True - F[i, j] = F[i+1, j-1]; ( s[i] = s[j] ) - F[i, j] = False; ( s[i] s[j] ) Bài 2.30 Xâu Palindrome Một xâu gọi đối xứng xâu đọc từ trái sang phải giống đọc từ phải sang trái Cho xâu S tìm số kí tự cần thêm vào sâu S để S trở thành xâu đối xứng xau_dx.inp Xau_dx.out Edbabcd ec Dữ liệu vào: xau_dx.inp gồm Gồm dòng xâu S Dữ liệu ra: Ghi vào tệp xau_dx.out - Dòng 1: Đưa số lượng kí tự cần chèn thêm vào - Dòng 2: Các kí tự cần chèn * Ý tưởng: - Gọi S2 xâu đảo xâu S1 ban đầu, T xâu chung dài S1 S2 Khi kí tự S1 khơng thuộc T kí tự cần chèn vào S1 để S1 trở thành xâu đối xứng - Bài tốn trở thành tìm dãy chung dài hai dãy tương ứng xâu S1 S2 phương pháp quy hoạch động Sử dụng mảng L[0 max,0 max] để lưu độ dài dãy chung dài với L[i,j] độ dài dãy chung dài hai dãy xâu s1 s2: 30 Khi đó: L[0,j] = với j  N (N = length(s1)) L[i,0] = với i  M (M = length(s2)) Với i  M , j  N : Nếu s1[i] = s2[j] L[i,j]:= L[i-1,j-1] + ngược lại L[i,j] = max{L[i-1,j], L[i,j-1]} Dạng Tìm xâu Phương pháp chung: Để tìm xâu xâu ban thỏa mãn điểu kiện cho trước thường sử dụng phương pháp vét cạn với liệu đầu vào nhỏ, nhiên nên sử dụng linh hoạt phương pháp khác phương pháp quy hoạch động trường hợp tốn có liệu lớn Bài 2.31 Đếm xâu Cho xâu s (có độ dài khơng vượt q 103) gồm ký tự từ 'a' đến 'z' Đếm số lượng xâu liên tiếp khác nhận từ xâu s Ví dụ: S = 'abab' có xâu là: a, b, ab, ba, aba,bab,abab * Ý tưởng: Lưu xâu có độ dài i (với i từ đến length(s)) vào mảng, sau xếp mảng tăng dần thực đếm số lượng xâu khác ta số lượng xâu có độ dài i Bài 2.32 Xâu Cho trước hai xâu kí tự S1 S2 Viết chương trình tính số lần lặp lại xâu S1 xâu S2 Dữ liệu: Vào từ tệp văn XAU.INP gồm:  Dòng chứa xâu S1  Dòng thứ hai chứa xâu S2 Kết quả: Ghi tệp văn XAU.OUT:  Chỉ dòng ghi số lần lặp lại xâu S1 xâu S2 Ví dụ: XAU.INP XAU.OUT Aba bababababa * Ý tưởng: Sử dụng hàm Pos(s1,s2) để xác định có hay không xuất xâu s1 xâu s2 Giả sử giá trị hàm trả i khác 0, ta tăng biến đếm lên xóa ký tự thứ i xâu s2, tiếp tục trình i=0 xâu s2 rổng 31 Bài 2.33 Chiếc nón kỳ diệu Một lần chương trình “Chiếc nón diệu kỳ”, phần chơi dành cho khán giả, thay đốn chữ khi, người dẫn chương trình tự quay “chiếc nón” cho lên hình trước mặt khán giả trường quay số ô mà kim thị qua “Chiếc nón” quay số ngun vòng, nên dãy số lên hình, số cuối trùng với số Sau đó, người dẫn chương trình mời khán giả cuối trường quay (chỉ nhìn thấy hình mà khơng nhìn thấy “chiếc nón”) cho biết nón có tối thiểu ô? Yêu cầu: Hãy trả lời câu hỏi người dẫn chương trình Dữ liệu: Vào từ tập tin văn CNDK.INP gồm hai dòng: + Dòng ghi số N số lượng số lên hình, (2  N  100) + Dòng ghi N số, số có giá trị không 32000 Kết quả: Ghi tập tin văn CNDK.OUT số tối thiểu “chiếc nón” Lưu ý: Các số dòng cách khoảng trắng Ví dụ: CNDK.INP CNDK.OUT 13 5313525313525 * Ý tưởng: Nhận thấy ghép toàn số lên hình (trừ số cuối cùng) vào xâu S xâu S ln tồn xâu s1 dài mà ghép liên tiếp số lần xâu s1 ta xâu s Số lần xuất xâu s1 kết cần tìm Bài tốn trở thành tìm xâu dài s1 Bài 2.34 Chuỗi lớn Cho chuỗi X=x1x2 xN xi số từ đến Y=y1y2 yM yi số từ đến M, N S=t0a46ui148t994x HẾT 34 Tài liệu tham khảo “Sách giáo khoa tin học lớp 8”, Hồ Sĩ Đàm, NXBGD 2003 “Sách giáo viên tin học lớp 8”, Hồ Sĩ Đàm, NXBGD 2003 “Sáng tạo thuật tốn lập trình”, Nguyễn Xuân Huy, 2008 “Giải toán máy tính nào” , Hồng Kiếm, XBGD 2003 “Cơ sở lập trình phổ thơng”, Nguyễn Quang Tấn, NXBGD 2004 “ Các khái niệm lập trình”, Ngơ Trung Việt, NXBTK 1993 "Những viên ngọc lập trình", Jon Bentley, NXBTK 2002 ”Tài liệu bồi dưỡng thường xuyên", Nguyễn Thanh Tiên, ĐHSP Huế 2005 “Một số vấn đề dạy học lập trình”, Lê Anh Phương, ĐHSP Huế 2006 10 “Thiết kế đánh giá thuật toán”, Trần Tuấn Minh ,ĐH Đà Lạt 2005 11 “Kỹ thuật phân tích giải thuật” , Nguyễn Văn Linh, ĐH cần Thơ, 2006 35 ...I Giải toán Tin Phần giới thiệu số bước thường vận dụng trình giải toán Tin Bước bước quan trọng hiểu rõ nội dung toán Đây yêu cầu quen thuộc người làm toán Để hiểu toán theo cách tiếp cận tin. .. dạng tốn bồi dưỡng mơn tin cho HSG THCS Các toán số học Để giải toán số học giáo viên cần cho học sình ứng dụng nhuần nhuyễn kiến thức số học THCS chủ yếu dựa vào phép toán DIV, MOD:  Thuật... khoa học có chủ đích nhằm kiểm tra tính tin cậy chương trình thu thực số cải tiến Chúng ta vận dụng cách tiếp cận để giải số toán cụ thể Những phần trình bày sử dụng vài kí pháp quen thuộc tin học,

Ngày đăng: 20/02/2020, 17:40

TỪ KHÓA LIÊN QUAN

w