Chu de 10 2015

34 9 1
Chu de 10 2015

Đ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

Kết quả: Ghi ra màn hình và ghi ra tệp văn bản SXXAU.OUT, mỗi phương án trên 1 dòng, trên dòng đó ghi số skc, danh sách XKC, số sks, danh sách XKS, tiếp đó ghi xâu S sau khi đã được sắp [r]

(1)LUYỆN THI HỌC SINH GIỎI MÔN TIN HỌC Thời gian làm bài: 150 phút CHỦ ĐỀ 10 XÂU ĐỐI XỨNG Tổng quan TT Tên bài Khúc đối xứng đầu tiên Sắp xếp xâu Xâu đối xứng dài File chương trình File liệu File kết Thời gian DXDAU.PAS DXDAU.INP DXDAU.OUT 1s/test SXXAU.PAS SXXAU.INP SXXAU.OUT 1s/test XAUDX.PAS XAUDX.INP XAUDX.OUT 1s/test Bài (6 điểm) KHÚC CON ĐỐI XỨNG ĐẦU TIÊN Xâu đối xứng là xâu kí tự, có không ít kí tự, và đọc từ trái sang phải hay từ phải sang trái giống Ví dụ ‘A’, ‘TET’, ‘CAC’ là các xâu đối xứng, còn các xâu ‘CAT’, ‘MEET’ không phải là xâu đối xứng Khúc xâu S là xâu gồm số kí tự liên tiếp xâu S Yêu cầu: Cho trước xâu kí tự S, có độ dài không quá 250 kí tự, cần: a) Tính độ dài D khúc đối xứng dài xâu S b) Xác định khúc đối xứng dài đầu tiên K xâu S, vị trí đầu (VTD), và vị trí cuối K S Dữ liệu: Đọc từ tệp DXDAU.INP, gồm nhiều phương án, phương án trên dòng, trên dòng đó ghi xâu S Kết quả: Đưa màn hình và ghi tệp DXDAU.OUT, phương án ghi trên dòng, trên dòng đó ghi ba số D, VTD, VTC, tiếp đó ghi khúc K tìm Ví dụ: DXDAU.INP DXDAU.OUT ACBC CBC NANGNANG 7 NANGNAN Bài (7 điểm) SẮP XẾP XÂU Cho xâu S gồm các chữ cái viết thường và chữ số, độ dài không quá 250 Khúc số xâu S là khúc S, gồm tất các chữ số liên tiếp Khúc chữ xâu S là khúc S, gồm tất các chữ cái liên tiếp Yêu cầu: a) Tìm số skc là số các khúc chữ, đối xứng, có xâu S, cùng với danh sách XKC chúng b) Tìm số sks là số các khúc số, đối xứng, có xâu S,cùng với danh sách XKS chúng c) Sắp xếp lại các kí tự xâu S cho: - các khúc số, các chữ số theo thứ tự tăng dần - các khúc chữ, các chữ cái theo thứ tự giảm dần Dữ liệu: Đọc vào từ tệp văn SXXAU.INP, gồm nhiều phương án, phương án trên dòng, trên dòng đó ghi xâu S Kết quả: Ghi màn hình và ghi tệp văn SXXAU.OUT, phương án trên dòng, trên dòng đó ghi số skc, danh sách XKC, số sks, danh sách XKS, tiếp đó ghi xâu S sau đã xếp lại, các danh sách XKC, XKS cần để cặp ngoặc vuông [].) Ví dụ: SXXAU.INP df443gfg234432jgudit7e7733 dfgfg234432jgudit7443e77334 SXXAU.OUT [gfg e] [234432 7] fd344ggf223344utjigd7e3377 [e] [234432] ggffd223344utjigd3447e33477 Bài (7 điểm) XÂU CON ĐỐI XỨNG DÀI NHẤT Cho trước xâu kí tự S, độ dài không quá 255 Xâu T gọi là xâu xâu S ta có thể xóa bớt số ký tự xâu S để nhận xâu T Ví dụ xâu T = ‘12345’ là xâu xâu S = ‘1a2b3c45d’ (2) Yêu cầu: Tìm xâu đối xứng T dài xâu S Dữ liệu: Đọc từ tệp văn XAUDX.INP, gồm nhiều phương án, phương án trên dòng, trên dòng đó ghi xâu S Kết quả: Ghi màn hình và ghi tệp văn XAUDX.OUT, phương án trên dòng, trên dòng đó ghi độ dài xâu T, tiếp đó ghi xâu T tìm Ví dụ: XAUDX.INP MADAM Abcbd XAUDX.OUT MADAM bcb TÓM TẮT LÝ THUYẾT I Hiểu thêm xâu ký tự Xâu ký tự (sau đây gọi tắt là xâu) là đoạn văn mà phần tử nó ký tự Ký tự có thể là: - Các chữ cái viết hoa: A, B, C, …, Z - Các chữ cái viết thường: a, b, c, …, z - Các chữ số: 0, 1, 2, …, (3) - Các dấu ngắt câu: chấm (.), phảy (,), chấm phẩy (;), chấm than (!), … - Các ký tự đặc biệt: ~, @, #, $, Xâu số là xâu ký tự biểu diễn số (số nguyên số thực) Ví dụ: ‘123’, ‘123.456’ là các xâu số, còn ‘123.456@234’ không phải là xâu số II Xâu đối xứng Xâu đối xứng là xâu mà đọc từ trái sang phải hay từ phải sang trái cho cùng kết Ví dụ: ‘abcba’, ‘121’ là các xâu đối xứng, còn ‘abcd’, ‘123.456’ không phải là xâu đối xứng Hiển nhiên xâu gồm ký tự là xâu đối xứng (trường hợp tầm thường) III Kiểm tra tính đối xứng xâu ký tự Để kiểm tra xâu ký tự S có đối xứng không, ta thực sau: đặt i = 1; j = length(S); Lặp lại chừng nào còn i<j Nếu S[i] <> S[j] thì trả false và kết thúc lặp Trái lại thì tăng i, giảm j Trả true IV Khúc và xâu Cần chú ý phân biệt hai khái niệm khúc và xâu Khúc (hoặc đoạn con) xâu ký tự S là xâu ký tự gồm các ký tự liên tiếp xâu S Nếu xâu S có N ký tự thì nó có không quá N*N khúc Để duyệt qua hết các khúc xâu S, ta dùng cách sau: Đặt N = length(S) Duyệt với i từ đến N-1 Duyệt với j từ i + đến N {Làm việc với khúc S[i j]} Xâu xâu ký tự S là xâu ký tự, nhận từ S cách xóa số ký tự nào đó S (các ký tự còn lại vần giữ nguyên thứ tự trước sau S) Nếu xâu S có N ký tự thì nó có đến 2N xâu con, số lượng lớn, vì khó (và thường không) duyệt hết các xâu S Rõ ràng khúc là xâu xâu chưa đã là khúc Ví dụ với xâu ‘1a2b34cde’ thì các xâu ‘1a2’ ‘b34c’ là các khúc (và là xâu con) còn ‘1234’ ‘abcde’ là các xâu (nhưng không phải là khúc con) GỢI Ý CÁCH GIẢI Bài - Tạo hàm DoiXung(ss) để kiểm tra tính đối xứng xâu ss Khởi tạo dx = true, ls = length(ss), l2 = ls / Duyệt với j từ đến l2 Nếu ss[j] <> ss[ls-j+1] thì dx = false, kết thúc lặp Đặt DoiXung = dx - Tìm đoạn đối xứng dài đầu tiên xâu S Khởi tạo l0 = length(S), D = 0, K = '' Duyệt với i từ đến l0 Duyệt với j từ đến l0-i+1 (4) tg := copy(S,i,j) Nếu DoiXung(tg) thì {Nhớ lại kết quả} ls := length(tg); Nếu D<ls thì {nhớ lại kết quả} D = ls {Độ dài} K = tg {xâu con} Bài - Tạo hàm DoiXung(ss) để kiểm tra tính đối xứng xâu ss (tương tự bài 1) - Tạo lệnh SapXep(st, vtd, hg) để xếp xâu st vị trí đầu vtd, theo hướng hg (hg = 1: xếp tăng, hg = -1: xếp giảm) Khởi tạo lst = length(st), lst1 = lst – delete(S,vtd,lst) {Xóa xâu st khỏi xâu S} Duyệt với i từ đến lst1 Duyệt với j từ i+1 đến lst Nếu (ord(st[i])-ord(st[j]))*hg>0 thì t = st[i] st[i] = st[j] st[j] = t Insert(st,S,vtd) {Chèn xâu st trở lại xâu S} - Tìm các xâu chữ và các xâu số S: Đặt i = Lặp lại i> length(S) Đặt hg = Nếu S[i] là chữ cái thì đặt hg = -1 st := ''; j := i; k := i; Lặp lại đến (S[j] là chữ cái và hg = 1) (S[j] là chữ số và hg = -1) đặt st = st + S[j] tăng j Nếu DoiXung(st) thì Nếu hg = -1 then {nhớ lại xâu chữ} Tăng skc xkc := xkc + st + ' ' Trái lại {nhớ lại xâu số} inc(sks) xks := xks + st + ' ' SapXep(st,k,hg) Đặt i = j Bài - Tạo hàm DX(ii, jj) để kiểm tra tính đối xứng xâu khúc từ ii đến jj xâu S - Dùng hàm đó để tìm tâm đối xứng S: Đặt N = length(S), tam = (N + 1) div 2, it = tam, jt = tam lmax = {độ dài xâu đối xứng dài nhất} kcmin = N {khoảng cách tự tâm đến tâm đối xứng} Duyệt với i từ đến n+1 Duyệt với j từ i+1 đến N Nếu DX(i,j) thì Đặt l = j-i+1 {độ dài xâu đối xứng tìm được} Nếu lmax <= l thì {chọn xâu dài hơn} lmax = l tt = (i + j) div {tâm xâu} kc = abs(tt-tam) {khoảng cách từ tâm đến tâm xâu mới} kcmin > kc thì {chọn xâu gần tâm hơn} đặt kcmin = kc, it = i, jt = j - Tạo hàm ConGap(ch, vt, phia) để kiểm tra xem có còn gặp ký tự biến ch phía đối diện hay không (phia = ‘T’: phía trái, phía = ‘P’: phía phải) Nếu (phia = 'T') thì đặt x := copy(S,1,vt) trái lại đặt x := copy(S,vt,N-vt+1) ConGap = (pos(ch,x)>0) - Tìm xâu đối xứng dài xâu S Đặt T := copy(S,it,jt-it+1); (5) Giảm it, tăng jt {mở rộng sang hai biên xâu S} Lặp lại mà (it>=1) và (jt<=N) Đặt cgp = ConGap(S[it],jt,'P'), cgt = ConGap(S[jt],it,'T') Nếu S[it] = S[jt] thì Đặt T = S[it] + T + S[jt], giảm it, tăng jt Trái lại thì {S[it] <> S[jt]} Nếu không cgt và không cgp thì Giảm it, tăng jt Trái lại thì Nếu không cgp thì giảm it trái lại {bo S[it]} Nếu không cgt thì tăng jt {bo S[jt]} Trái lại giảm it {bo S[it]} DỮ LIỆU ĐỂ KIỂM TRA BÀI Tệp DXDAU.INP (chú ý: liệu kéo dài đến dòng tụt vào tiếp theo) ACBC NANGNANG BNANGNANG IKACOBEGIGEBOCAHTM ABCDEFGHIHGFEDCBAIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZ ABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIIHGFEDCBAJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQ RSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZ ABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIGHIIHGIHGFEDCBAIHG FEDCBAJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZABC DEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZABCDEFGHIJKLMNOPQRSTUVXYZ Tệp DXDAU.OUT CBC 7 NANGNAN NANGNAN 13 15 ACOBEGIGEBOCA (6) 17 17 ABCDEFGHIHGFEDCBA 18 26 43 ABCDEFGHIIHGFEDCBA 24 51 74 ABCDEFGHIGHIIHGIHGFEDCBA DỮ LIỆU ĐỂ KIỂM TRA BÀI Tệp SXXAU.INP df443gfg234432jgudit7e7733 dfgfg234432jgudit7443e77334 df4437gfg234432jgudite7733567 df443231gfg234432jgudit7e2237733 df443447gfg2344321090jgudit7e7733 df443gfg234432jgudit74432egaqt7733 df443gfg234432jgudit74435e7733ghptu Tệp SXXAU.OUT [gfg e] [234432 7] fd344ggf223344utjigd7e3377 [e] [234432] ggffd223344utjigd3447e33477 [gfg] [234432] fd3447ggf223344utjiged3356777 [gfg e] [234432 7] fd123344ggf223344utjigd7e2233377 [gfg e] [7] fd344447ggf0012233449utjigd7e3377 [gfg] [234432] fd344ggf223344utjigd23447tqgea3377 [gfg e] [234432] fd344ggf223344utjigd34457e3377utphg DỮ LIỆU ĐỂ KIỂM TRA BÀI Tệp XAUDX.INP MADAM abcbd esystem edbabcd message azbzczdzez stackexchange 00_11_22_33_222_1_000 abcdefg_hh_gfe_1_d_2_c_3_ba Tệp XAUDX.OUT MADAM bcb esyse dbabd esse zzczz acxca 18 00_1_22_33_22_1_00 18 abcdefg_hh_gfedcba (7) MÃ NGUỒN BÀI (Tệp DXDAU.PAS) {Phan khai bao chung} uses crt; const tentep = 'DXDAU'; {Ten tep} var S: string; {Dau vao} D: byte; {Dau vao} K: string; {Dau ra} soPA, pa: byte; {QL phuong an} f: text; {Bien tep} {Dem so phuong an} procedure DemSoPA; BEGIN assign(f, tentep+'.INP'); reset(f); SoPA := 0; while (not EOF(f)) begin readln(f); inc(SoPA); end; close(f); END; {Doc du lieu cua phuong an pa} procedure DocPA; var i: integer; BEGIN assign(f, tentep+'.INP'); reset(f); {Bo qua cac pa truoc} i:=1; while (i<pa) begin readln(f); inc(i); end; {Doc du lieu cua phuong an pa} read(f,S); close(f); END; (8) {Kiem tra tinh doi xung} function DoiXung(ss: string): boolean; var ls,l2,j: integer; dx: boolean; BEGIN dx := true; ls := length(ss); l2 := ls div 2; for j:= to l2 if ss[j] <> ss[ls-j+1] then begin dx := false; break; end; DoiXung := dx; END; {Loi giai} Procedure DoanConDX; var i, i1, j, l0, ls: integer; tg: string; BEGIN l0 := length(S); D := 0; K := ''; for i:=1 to l0 for j:=1 to l0-i+1 begin tg := copy(S,i,j); ls := length(tg); if DoiXung(tg) then begin if D<ls then begin D := ls; K := tg; end; end; end; END; {Ghi ket qua man hinh va tep tin} procedure GhiKQ; BEGIN writeln(D,' ',K); assign(f, tentep+'.OUT'); if pa<=1 then rewrite(f) else append(f); writeln(f,D,' ',K); close(f); END; {Chuong trinh chinh} BEGIN clrscr; docSoPA; for pa:=1 to soPA begin docPA; DoanConDX; GhiKQ; end; writeln; write('Da xong Nhan ENTER de thoat.'); readln; END GIẢI THÍCH MÃ NGUỒN BÀI 1 Chương trình chính Sau gọi lệnh DemSoPA, vòng lặp For gọi các lệnh DocPA, DoanConDX, và GhiKQ Lệnh DemSoPA: đếm số phương án có tệp liệu Lệnh DocPA: đọc liệu phương án thứ pa Lệnh GhiKQ: ghi kết màn hình và tệp tin Lệnh DoanConDX: Tìm khúc đối xứng dài đầu tiên và độ dài nó, thuật giải đã nêu phần Gợi ý cách giải (9) MÃ NGUỒN BÀI (Tệp SXXAU.PAS) {Phan khai bao chung} uses crt; const tentep = 'SXXAU'; (10) (11) (12) (13) (14) (15) (16) (17) (18) (19) (20) (21) (22) (23) (24) dx := false; break; end; DoiXung := dx; END; {Sap xep} procedure SapXep(st: string; vtd: byte; huong: integer); var lst, lst1, i, i1, j: byte; t: char; BEGIN lst := length(st); lst1 := lst - 1; delete(S,vtd,lst); for i := to lst1 begin i1 := i + 1; for j:=i1 to lst if (ord(st[i])-ord(st[j]))*huong>0 then begin t := st[i]; st[i] := st[j]; st[j] := t; end; end; insert(st,S,vtd); END; {Sap xep lai xau theo yeu cau} Procedure SapXepXau; var i, i1, j, k, l, huong: integer; st: string; BEGIN sks := 0; skc := 0; xks := '['; xkc := '['; i := 1; repeat huong := 1; if S[i] in ['a' 'z'] then huong := -1; st := ''; j := i; k := i; repeat st := st + S[j]; inc(j); until ((S[j] in chucai) and (huong = 1)) or ((S[j] in chuso) and (huong = -1)) or (j>length(S)); if DoiXung(st) then if huong = then begin inc(skc); xkc := xkc + st + ' '; (25) end else begin inc(sks); xks := xks + st + ' '; end; SapXep(st,k,huong); i:=j; until i>length(S); delete(xks,length(xks),1); xks := xks + ']'; delete(xkc,length(xkc),1); xkc := xkc + ']'; END; if pa<=1 then rewrite(f) else append(f); writeln(f,sks,' ',xks,' ',skc,' ',xkc,' ',S); close(f); END; {Ghi ket qua man hinh va tep tin} procedure GhiKQ; BEGIN writeln(sks,' ',xks,' ',skc,' ',xkc,' ',S); assign(f, tentep+'.OUT'); {Chuong trinh chinh} BEGIN clrscr; docSoPA; for pa:=1 to soPA begin docPA; SapXepXau; GhiKQ; end; writeln; write('Da xong Nhan ENTER de thoat.'); readln; END GIẢI THÍCH MÃ NGUỒN BÀI Chương trình chính Sau gọi lệnh DemSoPA, vòng lặp For gọi các lệnh DocPA, SapXepXau, và GhiKQ Lệnh DemSoPA: đếm số phương án có tệp liệu Lệnh DocPA: đọc liệu phương án thứ pa Lệnh GhiKQ: ghi kết màn hình và tệp tin Lệnh SapXepXau: Tìm các thông tin và xếp lại xâu theo yêu cầu, thuật giải đã nêu phần Gợi ý cách giải MÃ NGUỒN BÀI (Tệp XAUDX.PAS) (26) {Phan khai bao chung} uses crt; const tentep = 'XAUDX'; {Ten tep} var S: string; T: string; {Dau vao} {Dau ra} (27) (28) (29) (30) (31) (32) (33) dec(jj); end; DX := true; END; {Tim xau doi xung gan tam nhat cua xau S} Procedure TimTamDX; var n1, i, i1, j, tt, lmax, l, kcmin, kc: byte; BEGIN N := length(S); n1 := N - 1; tam := (N + 1) div 2; it := tam; jt := tam; lmax := 1; kcmin := N; for i := to n1 begin i1 := i + 1; for j:= i1 to N if DX(i,j) then begin l := j-i+1; if lmax <= l then {chon xau dx dai hon} begin lmax := l; tt := (i + j) div 2; kc := abs(tt-tam); if kcmin > kc then {chon xau dx gan tam hon} begin kcmin := kc; it := i; jt := j; end; end; end; end; END; {con gap ch o phia tuong ung} function ConGap(ch: char; vt: byte; phia: char):boolean; var x: string; BEGIN if (phia = 'T') then x := copy(S,1,vt) else x := copy(S,vt,N-vt+1); ConGap := (pos(ch,x)>0); END; {Tim xau doi xung T cua xau S} Procedure TimT; var cgt, cgp: boolean; BEGIN (34) T := copy(S,it,jt-it+1); dec(it); inc(jt); while (it>=1) and (jt<=N) begin cgp := ConGap(S[it],jt,'P'); cgt := ConGap(S[jt],it,'T'); if S[it] = S[jt] then begin T := S[it] + T + S[jt]; dec(it); inc(jt); end else {S[it] <> S[jt]} if (not cgt) and (not cgp) then begin {bo ca S[it] va S[jt]} dec(it); inc(jt); end else if (not cgp) then dec(it) else {bo S[it]} if (not cgt) then inc(jt) else dec(it); {bo S[jt]} end; END; {Ghi ket qua man hinh va tep tin} procedure GhiKQ; BEGIN assign(f, tentep+'.OUT'); if pa<=1 then rewrite(f) else append(f); writeln(length(T),' ',T); writeln(f,length(T),' ',T); close(f); END; {Chuong trinh chinh} BEGIN clrscr; DemSoPA; for pa:=1 to soPA begin docPA; TimTamDX; TimT; GhiKQ; end; writeln; write('Da xong Nhan ENTER de thoat.'); readln; END GIẢI THÍCH MÃ NGUỒN BÀI Chương trình chính Sau gọi lệnh DemSoPA, vòng lặp For gọi các lệnh DocPA, TimTamDX, TimT, và GhiKQ Lệnh DemSoPA: đếm số phương án có tệp liệu Lệnh DocPA: đọc liệu phương án thứ pa Lệnh GhiKQ: ghi kết màn hình và tệp tin Lệnh TimTamDX: Tìm vị trí đầu it và vị trí cuối jt tâm đối xứng, thuật giải đã nêu phần Gợi ý cách giải Lệnh này gọi hàm DX(i,j) để kiểm tra tính đối xứng khúc từ i đến j xâu S Lệnh TimT: Tìm xâu đối xứng dài T xâu S, thuật giải đã nêu phần Gợi ý cách giải Lệnh này gọi hàm ConGap(ch,vt,phia) để kiểm tra xem có còn gặp ký tự biến ch bên phía đối diện không (35)

Ngày đăng: 28/09/2021, 04:50

Tài liệu cùng người dùng

  • Đang cập nhật ...