Tải bản đầy đủ - 0 (trang)
PHẦN II. NỘI DUNG

PHẦN II. NỘI DUNG

Tải bản đầy đủ - 0trang

Sáng kiến kinh nghiệm tin học



o Nếu A và B là các xâu có độ dài khác nhau và A là đoạn đầu của B

thì A nhỏ hơn B

Ví dụ: ‘May tinh’ < ‘May tinh cua toi’

o Hai xâu được coi là bằng nhau nếu như chúng giống nhau hồn

tồn:

Ví dụ: ‘TIN HOC’ = ‘TIN HOC’

d) Các hàm và thủ tục xử lý xâu, kí tự (Đây cũng là một trong các lý do tại

sao không xử dụng mảng các kí tự để khai báo cho xâu mặc dù cách thức

truy cập tới phần tử của xâu và mảng tương tự nhau – Nếu sử dụng mảng

thì ta sẽ khơng áp dụng được các hàm và thủ tục rất tiện lợi này).

Một số thủ tục chuẩn:

Delete(St, vt, n): xóa n kí tự của xâu St bắt đầu từ vị trí vt.

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

Val(St, x, m): Đổi giá trị xâu St thành số ghi giá trị vào biến X, nếu khơng

đổi được thì vị trí gây lỗi ghi trong m, nếu đổi thành cơng thì m = 0

Str(X, St): chuyển số X thành xâu kí tự lưu trong St.

Một số hàm chuẩn:

Copy(St, vt, n): sao chép từ xâu St, n kí tự bắt đầu từ vị trí vt.

Pos(S1, S2): tìm vị trí xuất hiện đầu tiên của S1 trong S2.

Length(St): cho độ dài xâu St.

Upcase(ch): cho chữ cái viết hoa tương ứng với chữ trong ch.

Chr(X): cho kí tự có mã X trong bảng mã ASCII.

Ord(ch): cho mã của kí tự ch trong bảng mã.

Concat(St1,St2,...StN): Hàm ghép nối các xâu St1,St2,...StN thành xâu ký

tự theo thứ tự đã viết. Các viết này tương tự như: ST := St1 + St2 + ... +

StN

2.1.2. Kiểu dữ liệu xâu trong TP và FP

2.1.2.1. Kiểu dữ liệu xâu trong TP

Trong TP xâu chỉ có độ dài khơng q 255 kí tự nên nếu như với bài tốn

có độ dài lớn hơn thì việc sử dụng kiểu xâu trong TP gặp khó khăn hơn rất nhiều

do vậy lựa chọn tốt hơn khi bạn vẫn muốn lập trình bằng ngơn ngữ Pascal đó là

sử dụng trình biên dịch FP. Đối với TP kiểu dữ liệu xâu thường dùng là String

chỉ có độ dài tối đa 255 kí tự. Nhưng hầu hết các bài tốn trong các đề thi học

sinh giỏi có độ dài xâu lớn hơn rất nhiều nên việc xử lý sẽ gặp rất nhiều khó

khăn. Do vậy, ta phải dùng tới trình biên dịch FP.

2.1.2.2. Kiểu dữ liệu xâu trong FP

Khi lập trình, chúng ta rất nhiều lần gặp vấn đề với các xâu tối đa 255 kí tự

của TP (chẳng hạn bài toán xâu đối xứng, bài toán đếm từ…). Ta có thể giải

Trang 6



Sáng kiến kinh nghiệm tin học



quyết vấn đề bằng mảng kí tự (array of char) nhưng khi đó ta lại khơng thể dùng

các phép tốn trên xâu rất mạnh của Pascal.

Khơng chỉ có cải tiến về kiểu nguyên, kiểu string trong FP cũng được cải

tiến rất tốt. Kiểu xâu kí tự trong FP khơng còn hạn chế 255 kí tự của TP nữa mà

có kích thước tối đa là khoảng 2 tỉ kí tự. Hơn nữa FP còn hỗ trợ kiểu xâu

Unicode (WideString). Nếu bạn vẫn muốn sử dụng kiểu String cũ của TP, bạn có

thể dùng kiểu ShortString hoặc String.

Trong mơi trường Windows, trình biên dịch FP có nhiều ưu thế hơn do tính

tương thích và hỗ trợ bộ nhớ lớn hơn.

Các kiểu dữ liệu xâu kí tự thường sử dụng trong FP: String, ShortString,

AnsiString, WideString.

4.



Một số câu hỏi chọn lọc liên quan đến kiểu dữ liệu xâu trong các đề

thi HS giỏi tỉnh Vĩnh Phúc những năm gần đây



Câu 1. (Bài 2 – Kì thi chọn HSG lớp 12 THPT – Năm học: 2014 – 2015)

Keyboard: Harry – người bạn của chúng ta đang gõ một đoạn văn bản bằng một

bàn phím đặc biệt với các ký tự được sắp xếp theo cách như sau:

qwertyuiop

asdfghjkl;

zxcvbnm,./

Thật không may, Harry bị khiếm thị, do vậy đôi khi nó cũng là vấn đề cho mỗi

lần muốn đặt tay lên bàn phím một cách chính xác. Harry vơ tình di chuyển cả

hai bàn tay của mình một vị trí cùng sang trái hoặc cùng sang phải. Điều đó có

nghĩa là hiện tại Harry đã bấm phải phím mà Harry khơng muốn

Chúng ta đã có một dãy các ký tự mà Harry đã gõ vào, giờ cần tìm lại chuỗi

nguyên bản ban đầu

Dữ liệu:

Dòng đầu ghi một ký tự là “R” – chuyển qua phải hoặc “L” chuyển qua

trái

Dòng tiếp theo ghi một dãy không quá 1000 ký tự - là chuỗi được đánh

máy bởi Harry. Dãy chỉ chứa các ký tự có trên bàn phím của Harry, chuỗi đã cho

cũng khơng có dấu cách, và bàn phím của Harry cũng khơng có khơng gian

trống, điều này đảm bảo rằng mặc dù tay có di chuyển thì Harry vẫn bấm vào

phím trên bàn phím mà khơng phải bấm ra ngồi bàn phím.

Kết quả: in ra một dòng chứa chuỗi kí tự nguyên bản.

Ví dụ:

Input



Output



R

s;;upimrrfod;pbr



allyouneedislove



Trang 7



Sáng kiến kinh nghiệm tin học



Thuật tốn:

Bước 1. Đọc ch1 tương ứng là kiểu kí tự lưu kí tự “L” hoặc “R”

Bước 2. Trong khi chưa kết thúc tệp ta tiếp tục thực hiện

B2.1. Đọc ch tương ứng với từng kí tự;

B2.2. Gán k1:=pos(ch,s1); k2:=pos(ch,s2); k3:=pos(ch,s3) với s1, s2, s3 là các

hằng số ứng với các xâu là từng dòng các kí tự như trên đề bài

B2.3. Nếu ch1=’R’ ta kiểm tra

B2.3.1. Nếu k1>0 thì s:=s+s1[k1-1];

B2.3.2. Nếu k2>0 thì s:=s+s2[k2-1]

B2.3.3. Nếu k3>0 thì s:=s+s3[k3-1]

B2.4. Nếu ch1=’L’ ta thực hiện:

B2.4.1. Nếu k1>0 thì s:=s+s1[k1+1];

B2.4.2. Nếu k2>0 thì s:=s+s2[k2+1]

B2.4.3. Nếu k3>0 thì s:=s+s3[k3+1]

Bước 3. Đưa ra xâu cần tìm: s

Code:

const



s1='qwertyuiop';

s2='asdfghjkl;';

s3='zxcvbnm,./';



var f,g:text; ch,ch1:char;

k1,k2,k3:byte;

s:ansistring;

BEGIN

assign(f,'keyboard.inp'); reset(f);

assign(g,'keyboard.out'); rewrite(g);

readln(f,ch1); s:='';

while not eof(f) do

begin

read(f,ch);

k1:=pos(ch,s1);k2:=pos(ch,s2); k3:=pos(ch,s3);

if ch1='R' then

begin

if k1>0 then s:=s+s1[k1-1];

if k2>0 then s:=s+s2[k2-1];

if k3>0 then s:=s+s3[k3-1];

end else

Trang 8



Sáng kiến kinh nghiệm tin học



begin

if k1>0 then s:=s+s1[k1+1];

if k2>0 then s:=s+s2[k2+1];

if k3>0 then s:=s+s3[k3+1];

end;

end;



writeln(g,s);



close(f); close(g);

END.



Câu 2. (Bài 3 – Kì thi chọn HSG lớp 10 THPT – Năm học: 2013 – 2014)

Cho bảng kích thước

được chia thành lưới ô vuông đơn vị. Các hàng

được đánh số từ

theo chiều từ trên xuống dưới. Các cột được đánh số từ

theo chiều từ trái qua phải. Ô nằm trên giao của hàng và cột được

gọi là ô

và trên đó ghi ký tự , kí tự này là chữ cái latin in hoa hoặc dấu #.

Mỗi từ trong bảng là một dãy liên tiếp các chữ cái trên cùng một hàng (tính từ

trái qua phải) hoặc một dãy liên tiếp các kí tự trên cùng một cột (tính từ trên

xuống dưới) sao cho hai từ liên tiếp trên cùng một hàng hoặc trên cùng một cột

cách nhau ít nhất bởi một dấu #. Yêu cầu: Tìm từ lớn nhất theo thứ tự từ điển.

Dữ liệu:

 Dòng Hai số nguyên dương

cách nhau ít nhất một dấu cách

 Dòng

: Dòng thứ

ghi ký tự liền nhau, kí tự thứ là

Kết quả: Ghi ra từ lớn nhất theo thứ tự từ điển.

Ràng buộc:

Ví dụ:

crosswrd.inp



crosswrd.out



45

#DACA

DA##B

ABB#B

ABBAC



DACA



Thuật tốn: Với những test có m, n nhỏ ta có thể sử dụng mảng 2 chiều để thực

hiện bài toán sẽ dễ dàng hơn nhưng với test lớn, chẳng hạn như với m, n mang

giá trị tối đa theo yêu cầu đề bài thì sử dụng mảng 2 chiều sẽ tốn bộ nhớ và với

những máy tính thơng thường hiện nay thì khơng thể chạy được, do vậy ta chỉ sử

dụng kiểu xâu lớn là ansistring, nhưng khi không sử dụng mảng 2 chiều thì việc

đọc và xử lý dữ liệu sẽ mất nhiều thời gian hơn do ta phải đọc từng kí tự.

Các bước xây dựng thuật tốn:



Trang 9



Sáng kiến kinh nghiệm tin học



Lưu ý về việc sử dụng các biến s, max kiểu ansistring; ch kiểu char để đọc từng

kí tự trong xâu. Sử dụng thêm mảng xâu a kiểu ansistring có tối đa 1000 kí tự.

Bước 1. Đọc n, m {m tương ứng là số cột, n tương ứng là số hàng)

Bước 2. {Ta sẽ đọc dữ liệu và xử lý dữ liệu theo hàng ngang trước. Sau khi kết

thúc quá trình xử lý này ta sẽ thu được xâu lớn nhất theo hàng ngang của mảng

kí tự}

- B2.1. i:=1 ,gán s:=’’; max:=s

- B2.2. Trong khi i<=n ta thực hiện

o B2.2.0. Gán j:=1;

o B2.2.1. Trong khi j<=m thực hiện đọc dữ liệu bằng thủ tục

read(f,ch) và chuyển sang B2.2.2

o B2.2.2. Nếu ch=’#’ và s<>’’ thì kiểm tra max
o B2.2.3. Nếu ch<>’#’ thì s:=s+ch

o B2.2.4. Tăng j lên 1 đơn vị

o B2.2.5. Kiểm tra nếu j>m thì sử dụng lệnh xuống dòng ở tệp f để

xuống đầu dòng tiếp theo đọc dữ liệu và kiểm tra nếu max
max:=s, s:=’’và chuyển sang B2.3. Nếu j<=m thì quay trở lại

B2.2.1

- B2.3. Tăng i và quay lại B2.2.

- B2.4. Thực hiện đóng tệp f (close(f))  mở tệp để đọc reset(f) để bắt đầu

đọc lại dữ liệu theo hàng dọc, nhưng trước đó phải sử dụng lệnh readln(f)

để bỏ qua dòng đầu tiên chứa 2 số n và m

Bước 3. {Đọc dữ liệu và xử lý dữ liệu theo hàng dọc, với việc xử lý theo hàng

dọc sẽ tốn thời gian hơn một chút}

- B3.1. Khởi tạo mảng a[i] có i chạy từ 1 đến m là rỗng

- B3.2. Gán j:=1 {chỉ số hàng}

- B3.3. Trong khi j<=n thì tiếp tục thực hiện

o B3.3.0. Gán i:=1

o B3.3.1. Trong khi i<=m thì thực hiện đọc dữ liệu bằng thủ tục

read(f,ch)

o B3.3.2. Nếu ch=’#’ và a[i] khác rỗng thì kiểm tra nếu max
lại max:=a[i] và a[i]:=’’ {rỗng}

o B3.3.3. Nếu ch<>’#’ thì a[i]:=a[i]+ch

o B3.3.4. Tăng I lên 1 đơn vị

o B3.3.5. Nếu i>m thì sử dụng lệnh readln(f) đưa con trỏ tệp xuống

đầu dòng tiếp theo còn i<=m thì quay lại B3.3.1

- B3.4. Tăng j lên 1 đơn vị



Trang 10



Sáng kiến kinh nghiệm tin học



- B3.5. Kiểm tra nếu j>n thì thực hiện cho biến k chạy từ 1 đến m nếu

a[k]>max thì gán max:=a[k] và chuyển sang Bước 4 còn khơng thì quay

trở lại B3.3.

Bước 4. Đưa ra max và kết thúc

Code:

VAR F,G:TEXT;

s,max:ansistring;ch:char;

a:array[1..1000] of ansistring;

i,j,m,n,k: integer;

BEGIN

assign(f,'crosswrd.inp'); reset(f);

assign(g,'crosswrd.out'); rewrite(g);

readln(f,n,m);

s:=''; max:=s; i:=1;

{Tim xau lon nhat theo hang ngang}

while (i<=n) do

begin

j:=1;

while j<=m do

begin

read(f,ch);

if (ch='#')and(s<>'') then

begin

if max
if (ch<>'#') then s:=s+ch;

inc(j);

if j>m then {Kiem tra xem ket thuc dong

chua}

begin

readln(f); {Dua tro chuot xuong

dau dong tiep theo}

if max
end;

end; inc(i);

end;

{Tim xau max theo hang doc}

close(f); reset(f);readln(f); {Mo lai tu dau tep va

xuong 1 dong}

for i:=1 to m do a[i]:='';

j:=1;

while j<=n do

begin

i:=1; while i<=m do

Trang 11



Sáng kiến kinh nghiệm tin học



begin

read(f,ch);

if (ch='#')and(a[i]<>'') then begin

if max
end;

if ch<>'#' then a[i]:=a[i]+ch;

inc(i);

if i>m then readln(f);

end;

inc(j); if j>n then

for k:=1 to m do

if (a[k]>max)then max:=a[k];

end;

write(g,max,length(max));

close(f); close(g);

END.



Với chương trình trên nếu như dữ liệu đầu vào gồm mảng 1000x1000 gồm tồn

các kí tự khác ‘#’ thì chương trình trên vẫn chưa giải quyết được.

Câu 3. (Bài 2 – Kì thi chọn HSG lớp 10 THPT – Năm học: 2012 – 2013)

Xâu moo: S[0]:='moo';

Với xâu k>=0, s[k+1]:=s[k]+'mo...'+s[k] trong đó 'mo.....' gồm k+3 kí tự 'o'

Chẳng hạn:

s[0]:='moo';

s[1]:='moomooomoo';

s[2]:='moomooomoomoooomoomooomoo'

Yêu cầu: cho n≤109, tất cả các xâu có độ dài khơng nhỏ hơn n đều có kí tự thứ n

giống nhau, yêu cầu in ra kí tự thứ n đó, là 'm' hay 'o'

Ví dụ: n=11  ‘m’

Thuật tốn:

Bước 1. Nếu n>109 thì kí tự cuối cùng là ‘o’

Bước 2. Gán s1:=’moo’; k:=0;

Bước 3. Nếu n≤3 thì kí tự cần tìm là s1[n]

Bước 4. Nếu 3≤n≤109 thì

B4.1. j:=3; st:=’moo’

B4.2. Trong khi j
Tăng k lên 1 đơn vị; st:=st+’o’; s2:=s1; s1:=s2+st+s2; j:=length(s1)

B4.3. Nếu j=n thì kí tự cần tìm là ‘o’ còn ngược lại: d1:=length(s1)

Trong khi j>n thực hiện: giảm j, giảm d1.

Kết quả s1[d1]

Trang 12



Sáng kiến kinh nghiệm tin học



Code:

var s,st,s1,s2: ansistring;

k,n,j,d1: int64;

begin

readln(n);

s1:='moo'; k:=0;

if n>1000000000 then write('o') else

if n<=3 then write(s1[n]) else

begin

j:=3;st:='moo';

while j
begin

inc(k);st:=st+'o';s2:=s1;s1:=s2+st+s2;

j:=length(s1);

end;

if j=n then write('o') else

begin

d1:=length(s1);

while j>n do

begin

dec(j); dec(d1);

end; write(s1[d1]);

end;

end;

readln;

end.



Câu 4. (Bài 3 – Kì thi chọn HSG lớp 12 THPT – Năm học: 2012 – 2013)

(Tương tự Bài 2 – Kì thi chọn HSG lớp 10 THPT – Năm học: 2010 – 2011)

Số đẹp. Theo quan niệm của khoa học huyền bí phương Đơng, số 6 được

coi là LỘC, số 8 được coi là PHÁT. Nhiều người cố gắng sở hữu các số này để

sử dụng cho số điện thoại, biển số xe,… Số đẹp là số trong biểu diễn thập phân

chỉ chứa 2 số trên. Dãy các số đẹp theo thứ tự là: 6, 8, 66, 68, 86, 88,…

Yêu cầu: tìm số đẹp thứ k (1≤k≤109)

Hướng dẫn thuật toán: với bài tập dạng này các bạn hãy vẽ dạng cây đồ thì với

bên trái là số nhỏ hơn, bên phải là số lớn hơn rồi lần lượt đánh trọng số từ 1, 2,

… Sau đó các bạn sẽ hiểu quy luật dựa vào code sau:

var k:int64;

s:ansistring;

begin

readln(k); {Nhap du lieu}

s:='';

Trang 13



Sáng kiến kinh nghiệm tin học



while k>2 do

begin

if k mod 2=0 then

begin

k:=k div 2-1; s:='8'+s;

end else

begin

k:=k div 2; s:='6'+s;

end;

end;

if k=1 then s:='6'+s;

if k=2 then s:='8'+s;

write(s); readln

end.



Câu 5. (Bài 3 – Kì thi chọn HSG lớp 10 THPT – Năm học: 2011 – 2012)

Số lớn nhất

Cho xâu S độ dài N là biểu diễn thập phân của một số nguyên dương, hãy tìm số

lớn nhất nhận được bằng cách gạch bỏ đi N chữ số trong xâu S

Dữ liệu: cho trong file văn bản NUMMAX.INP

- Dòng đấu: ghi hai số nguyên N và K, cách nhau bởi một dấu cách

- Dòng thứ hai: ghi xâu S gồm N chữ số, chữ số đầu tiên luôn khác 0

Kết quả: ghi ra file văn bản NUMMAX.OUT kết quả tìm được trên một dòng

duy nhất.

Điều kiện: 1≤k
Ví dụ

NUMMAX.INP



NUMMAX.OUT



NUMMAX.INP



NUMMAX.OUT



31

991



99



42

1924



94



Thuật toán:

Bước 1. M:=n-k với m là số chữ số cần giữ lại

W:=’’ với w là xâu sau khi đã gạch bỏ đi k chữ số; vt:=1;

Bước 2. Trong khi length(w)
sang Bước 3

B2.1. max:=s[vt] trong đó s là xâu ban đầu; vt1:=vt

B2.2. Xét từ vị trí vt tới vị trị n-(m-length(w))+1 của xâu s (j=vtn-(mlength(w))+1. Nếu max
B2.3. w:=w+max; vt:=vt1+1 rồi quay lại Bước 2

Trang 14



Sáng kiến kinh nghiệm tin học



Bước 3. Đưa ra xâu w

Code:

VAR k,n,vt,m,j,vt1:longint;

s,w:ansistring;

max:char; g,f:text;

BEGIN

Assign(f,’nummax.inp’);reset(f);

Assign(g,’nummax.out’;rewrite(g);

readln(f,n,k); readln(f,s);

m:=n-k; {So chu so can giu lai}

w:=''; {xau can tim} vt:=1;

while length(w)
begin

max:=s[vt]; vt1:=vt;

for j:=vt to n-(m-length(w))+1 do

if max
max:=s[j]; vt1:=j;

end;

w:=w+max; vt:=vt1+1 ;

end;



write(g,w);



close(f); close(g);

END.



Câu 6. (Bài 3 – Kì thi chọn HSG lớp 10 THPT – Năm học: 2010 – 2011)

Xâu con đối xứng:

Với mỗi xâu T, ta kí hiệu Tr là xâu nhận được từ T bằng cách viết T theo chiều từ

phải qua trái, chẳng hạn (abc) r = cba. Mỗi xâu T được gọi là xâu đối xứng nếu T

= Tr, chẳng hạn abccba, xyzyx là các xâu đối xứng.

Cho xâu S, xác định độ dài xâu con đối xứng dài nhất của S

Dữ liệu (spalin.inp): Chứa xâu S, độ dài không vượt quá 1000, chỉ gồm các chữ

cái latin a..z, A..Z

Kết quả (spalin.out): số nguyên là độ dài xâu con đối xứng dài nhất của S

Ví dụ:

Spalin.inp



Spalin.out



Aaaaxyyxxyyxbbbb



8



Thuật tốn:



Trang 15



Sáng kiến kinh nghiệm tin học



Bước 1. Viết hàm đối xứng có kiểu trả về là true nếu xâu đối xứng còn trả về

false nếu xâu khơng là xâu đối xứng

Bước 2. Kiểm tra xâu s đối xứng thì kết quả là length(s) còn ngược lại chuyển

sang bước 3

Bước 3. Gán d:=length(s)-1 {Sử dụng d để kiểm tra từ xâu có độ dài lớn hơn tới

xâu có độ dài nhỏ dần}

Bước 4. Trong khi d>0 thì thực hiện

B4.1. Cho I chạy từ 1 tới length(s)-d+1 thì thực hiện:

B4.1.1. st:=copy(s,I,d);

B4.1.2. Kiểm tra nếu st là đối xứng thì in ra d chính là độ dài của xâu con đối

xứng dài nhất và sử dụng break để thoát khỏi vòng lặp

B4.2. Kiểm tra nếu khi chưa tìm được xâu đối xứng thì tiếp tục giảm d còn đã

tìm được xâu đối xứng thì gán d:=0 để thốt khỏi vòng lặp ở Bước 4

Code:

Var g, f:text;d, max, i:word; s, st:ansistring;

{Ham kiem tra tinh doi xung cua mot xau}

Function dx(s1:ansistring):boolean;

Var



tg:boolean; j:word;



begin

tg:=true;

for j:=1 to length(s1) div 2 do

if s1[j]<>s1[length(s1)-j+1] then

begin tg:=false;



break;end;



dx:=tg;

end;

BEGIN

assign(f,'spalin.inp'); reset(F);

assign(g,'spalin.out'); rewrite(G);

readln(f,s);

if dx(s) then write(g,length(S)) else

begin

d:=length(s)-1;

while d>0 do

begin

for i:=1 to length(s)-d+1 do

begin

st:=copy(s,i,d);

Trang 16



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

PHẦN II. NỘI DUNG

Tải bản đầy đủ ngay(0 tr)

×