Năm học 2002-2003 Bài 1


DÃY HÌNH CHỮ NHẬT LỒNG NHAU



tải về 440.12 Kb.
trang4/4
Chuyển đổi dữ liệu23.07.2016
Kích440.12 Kb.
#2580
1   2   3   4

DÃY HÌNH CHỮ NHẬT LỒNG NHAU

(Bài 4 – Tuyển sinh 2007 - 2008)

Trên mặt phẳng tọa độ cho N hình chữ nhật với các cạnh song song với hệ trục tọa độ, các hình chữ nhật được đánh số từ 1 tới N. Hình chữ nhật thứ i được cho bởi 4 số nguyên dương xi1, i1, xi2, yi2, trong đó (xi1, i1) là tọa độ đỉnh trái dưới, còn (xi2, i2) là tọa độ đỉnh phải trên. Ta nói rằng hình chữ nhật thứ I nằm trong hình chữ nhật thứ j nếu trên mặt phẳng tọa độ, mọi điểm của hình chữ nhật i đều thuộc hình chữ nhật j.



Yêu cầu: Với N hình chữ nhật cho trước, hãy tìm K hình chữ nhật với chỉ số i1, i2, …, iK sao cho hình i1 nằm trong hình i2, hình i2 nằm trong hình i3, …, hình iK-1 nằm trong hình iK và K là lớn nhất. Biết rằng hai hình chữ nhật bất kì trong N hình chữ nhật đã cho hoặc rời nhau hoặc một trong hai hình nằm trong hình còn lại.

Dữ liệu: Vào từ file văn bản HCN.INP:

  • Dòng đầu tiên chứa số nguyên dương N (1N100).

  • N dòng tiếp theo, dòng thứ i chứa 4 số nguyên dương xi1, i1, xi2, yi2.

Kết quả: Ghi ra file văn bản HCN.OUT số K tìm được.

Ví dụ:

HCN.INP




HCN.OUT

3

1 1 7 4


3 1 6 6

2 2 5 4





2

Lời giải:

Bước 1, ta sắp xếp các hình chữ nhật theo thứ tự giảm dần của diện tích. Điều này đảm bảo một hình chữ nhật chỉ có thể bị bao bởi một hình chữ nhật xuất hiện phía trước nó. Đoạn chương trình sau thực hiện việc sắp xếp:

for i:=1 to n-1 do

for j:=i+1 to n do

if (dientich(h[i])

begin


tam:=h[i];h[i]:=h[j];h[j]:=tam;

end;


Giả sử các hình chữ nhật đã được sắp xếp là h1, h2, ..., hn. Ta gọi f[i] là độ dài lớn nhất của chuỗi hình chữ nhật lồng nhau kết thúc tại hình hi. Để tính f[i], ta tìm vị trí j lớn nhất sao cho j < i là hình chữ nhật hj bao hình chữ nhật hi, khi đó f[i]=f[j]+1. Nếu không tồn tại vị trí j thì hình chữ nhật hi không bị bao bởi hình chữ nhật nào và f[i]=1:

f[i]:=1; {khởi tạo giá trị ban đầu cho f[i]}

for j:=i-1 downto 1 do

if bao(h[j],h[i]) then {j là vị trí lớn nhất mà hình chữ nhật

h[j] bao hình chữ nhật h[i]}

begin


f[i]:=f[j]+1; {tính f[i] theo f[j]}

break; {thoát khỏi vòng lặp}

end;

if (f[i]>kq) then kq:=f[i]; {cập nhật lại kết qủa}



Chương trình:

const


finp='hcn.inp';

fout='hcn.out';

MAXN=105;

type hcn=record x1,y1,x2,y2: longint; end;

var

h: array[1..MAXN] of hcn;



f: array[1..MAXN] of longint;

i,j,n,kq: longint;

tam:hcn;

function dientich(a:hcn):longint;

begin

with a do dientich:=(x2-x1)*(y2-y1);



end;

function bao(a,b:hcn):boolean;

begin

bao:=(a.x1<=b.x1) and (b.x2<=a.x2) and



(a.y1<=b.y1) and (b.y2<=a.y2);

end;


begin

assign(input,finp);

reset(input);

assign(output,fout);

rewrite(output);

readln(n);

for i:=1 to n do

with h[i] do

readln(x1,y1,x2,y2);

for i:=1 to n-1 do

for j:=i+1 to n do

if (dientich(h[i])

begin

tam:=h[i];h[i]:=h[j];h[j]:=tam;



end;

kq:=0;


for i:=1 to n do

begin


f[i]:=1;

for j:=i-1 downto 1 do

if bao(h[j],h[i]) then

begin


f[i]:=f[j]+1;

break;


end;

if (f[i]>kq) then kq:=f[i];

end;

writeln(kq);



close(input);

close(output);

end.

Năm học 2008-2009

Bài 1: Mã hoá

Để quản lý tốt các hồ sơ trong kỳ thi tuyển sinh, hội đồng tuyển sinh trường PTNK đã quyết định đánh số các hồ sơ theo một phương pháp khoa học. Mã hồ sơ của thí sinh là một chuỗi gồm 10 chữ số. Tuy nhiên không phải bất kỳ chuỗi 10 chữ số nào cũng là mã hồ sơ hợp lệ bởi vì hội đồng tuyển sinh đưa ra một quy định ràng buộc chặt chẽ cho các chữ số đó. Nếu M=a1a2..a10 là một mã hồ sơ thì M phải thỏa mãn ràng buộc:

Nếu đặt S(M)=1a1+2a2+3a3+…+10a10 thì S(M) phải là một số chia hết cho 11.

Nhờ quy định này, trong những trường hợp do sơ xuất có một chữ số trong mã hồ sơ bị mờ, không đọc được thì ta vẫn có thể xác định được giá trị của nó. Ví dụ như: (quy ước ? là chữ số bị mờ):



  • Với M=00000000?1 thì có thể suy ra chữ số bị mờ là 5 vì theo ràng buộc, để S(M) là một số chia hết cho 11 nó chỉ có thể có giá trị là 55.

  • Tương tự với M=00000001?1 thì có thể suy ra chữ số bị mờ là 9.

  • Tương tự với M=00722?0858 thì có thể suy ra chữ số bị mờ là 6.

Yêu cầu: Hãy viết chương trình giúp hội đồng tuyển sinh suy ra được chữ số bị mờ trong mã hồ sơ.

Dữ liệu: Vào từ file văn bản ENCODE.INP có chứa mã hồ sơ có 1 chữ số bị mờ được thay bằng dấu chấm hỏi.

Kết quả: Ghi ra file văn bản ENCODE.OUT chứa giá trị của chữ số bị mờ trong mã hồ sơ đã cho.

Ví dụ:


ENCODE.INP

00000000?1

ENCODE.OUT

5

00000001?1



9

00722?0858

6

Lời giải:

Ta thử thay từng chữ số từ 0 đến 9 vào vị trí "?" và tính xem điều kiện S(M) chia hết cho 11 có được thoả mãn hay không như đoạn chương trình sau đây:

for i:=1 to 10 do

{r là tổng các số hạng của S(M) trừ vị trí có dấu ‘?’}

if (s[i]<>'?') then r:=(r+i*(ord(s[i])-ord('0'))) mod 11;

i:=pos('?',s); {i là vị trí của dấu ‘?’}

for d:=0 to 9 do {duyệt qua tất cả các chữ số từ 0 đến 9}

if (r+i*d) mod 11 = 0 then {kiểm tra xem S(M) có chia hết cho 11}

begin

writeln(d); {d chính là chữ số cần tìm}



break; {thoát khỏi vòng lặp}

end;


Chương trình:

const


finp='encode.inp';

fout='encode.out';

var

s: string;



i, r, d: longint;

c: char;


begin

assign(input,finp);

reset(input);

assign(output,fout);

rewrite(output);

readln(s);

for i:=1 to 10 do

if (s[i]<>'?') then r:=(r+i*(ord(s[i])-ord('0'))) mod 11;

i:=pos('?',s);

for d:=0 to 9 do

if (r+i*d) mod 11 = 0 then

begin


writeln(d);

break;


end;

close(input);

close(output);

end.


Bài 2: Biến đổi dãy số

Cho dãy các số nguyên khác nhau đôi một a gồm n số a1, a2, ..., an và dãy số nguyên b gồm n số b1, b2, ..., bn. Trên dãy số a ta có thể áp dụng phép biến đổi T(i) thực hiện phép hoán vị giá trị hai phần tử ai và ai+1 (0i1, Ti2, …, Tik sao cho khi áp dụng, dãy a ban đầu sẽ biến thành dãy b.

Ví dụ nếu dãy a là 1, 3, 2, 4 và dãy b là 2, 1, 3, 4 thì ta có thẻ sử dụng dãy 2 phép biến đổi T(2) và T(1) để biến đổi a thành b.

Yêu cầu: Cho hai dãy số a, b . Hãy chỉ ra một dãy các phép biến đổi a thành b hoặc cho biết không tồn tại dãy biến đổi như vậy.

Dữ liệu: Vào từ file văn bản EXARRAY.INP gồm 3 dòng:


  • Dòng đầu tiên chứa số nguyên n là số lượng phần tử của mỗi dãy số (n<=100).

  • Dòng thứ hai chứa n số nguyên đôi một khác nhau ứng với các phần tử của dãy số a.

  • Dòng cuối cùng chứa n số nguyên ứng với các phần tử của dãy số b.

Các số trong 2 mảng a và b đều có giá trị nằm trong đoạn [-10000,10000].

Kết quả: ghi ra file văn bản EXARRAY.OUT

  • Nếu không thể biến đổi a thành b, file chứa số duy nhất số -1.

  • Trong trường hợp ngựoc lại, file sẽ gồm 2 dòng:

    • Dòng đầu tiên chứa số nguyên k là số lượng phép biến đổi cần áp dụng.

    • Dòng thứ hai chứa k số nguyên duơng i1, i2, …, ik ứng với các phép biến đổi Ti1, Ti2, …, Tik tìm được.

Hai số liên tiếp trên cùng một dòng được ghi cách nhau bởi một dấu cách.

Ví dụ:

EXARRAY.INP

4

1 3 2 4


2 1 3 4

EXARRAY.OUT

2

2 1


EXARRAY.INP

1

5



2

EXARRAY.OUT

-1

Lời giải:

Thuật toán của ta đơn giản như sau: tìm b[1] trong dãy a rồi di chuyển lên đầu dãy a, sau đó lại tìm b[2] rồi di chuyển lên vị trí thứ hai của dãy a, ... Nếu tại một bước ta không tìm thấy số tương ứng trong dãy a thì in ra -1.

Đoạn chương trình sau thể hiện thuật toán:

for i:=1 to n do {duyệt qua tất cả các phần tử của dãy b}

begin

vt[i]:=0; {vt[i] là vị trí xuất hiện của b[i] trong dãy a}



for j:=i to n do {duyệt qua các phần tử của dãy a để tìm số b[i]}

if (a[j]=b[i]) then {tìm đặt b[i]}

begin

vt[i]:=j; {cập nhật lại vt[i]}



break; {thoát khỏi vòng lặp}

end;


if (vt[i]<>0) then {nếu tìm được số b[i]}

begin


kq:=kq+vt[i]-i; {cần thực hiện thêm vt[i]-i phép biển đổi

để đưa số từ vị trí vt[i] về vị trí i}

for j:=vt[i]-1 downto i do trao(j) {thực hiện biến đổi!}

end


else

begin {nếu không tìm được số b[i]}

writeln(-1); {in ra -1}

exit; {thoát khỏi thủ tục}

end;

end;


Chương trình:

const MAXN=102;

finp='exarray.inp';

fout='exarray.out';

var n: longint;

a,b:array[1..MAXN] of longint;

procedure nhap;

var i: longint;

begin

readln(n);



for i:=1 to n do read(a[i]);

for i:=1 to n do read(b[i]);

end;

var kq: longint;



vt: array[1..MAXN] of longint;

procedure trao(i: longint);

var tam: longint;

begin


tam:=a[i]; a[i]:=a[i+1]; a[i+1]:=tam;

end;


procedure xuly;

var i, j, tam: longint;

begin

for i:=1 to n do



begin

vt[i]:=0;

for j:=i to n do

if (a[j]=b[i]) then

begin

vt[i]:=j;



break;

end;


if (vt[i]<>0) then

begin


kq:=kq+vt[i]-i;

for j:=vt[i]-1 downto i do trao(j)

end

else


begin

writeln(-1);

exit;

end;


end;

writeln(kq);

for i:=1 to n do

for j:=vt[i]-1 downto i do

write(j,' ');

end;


begin

assign(input,finp);

reset(input);

assign(output,fout);

rewrite(output);

nhap;


xuly;

close(input);

close(output);

end.


Bài 3: Biến đổi bảng

Xét bảng vuông gồm n dòng và n cột. Các dòng được đánh số từ 1 đến n từ trên xuống dưới. Các cột được đánh số từ 1 đến n từ trái sang phải. Ô nằm ở vị trí dòng i và cột j của bảng được gọi là ô (i,j). Trên bảng A đã cho, khoảng cách từ ô (i,j) đến ô (p,q) được tính bằng |i-p|+|j-q|. Tại ô (i,j) của bảng A ghi số nguyên không âm aij, i=1,2,…,n; j=1,2,..,n. Dựa vào các số được ghi trên bảng A, người ta cần xây dựng một bảng B cùng kích thước với A mà trên đó ô (i,j) của bảng B sẽ được ghi số bij xác định như sau:



  • Nếu aij > 0 thì bij = aij

  • Nếu aij = 0 thì bij có giá trị bằng giá trị apq của ô (p,q) gần ô (i,j) nhất trong số các ô có giá trị khác không trên dòng i và cột j của bảng A. Trong truờng hợp có nhiều ô khác không có cùng khoảng cách nhỏ nhất đến (i,j) thì ô (p,q) đựoc chọn là ô chứa số lớn nhất trong chúng. Nếu tất cả các phần tử của dòng i và cột j đều có giá trị 0 thì bij = 0.

Yêu cầu: cho bảng A, hãy tìm bảng B.

Dữ liệu: vào từ file văn bản NZTABLE.INP gồm:

  • Dòng đầu tiên ghi số nguyên dương n (n ≤ 50)

  • Dòng thứ i trong số n dòng tiếp theo ghi n số nguyên không âm ai1, ai2, …, ain là các số trên dòng thứ i của bảng, i=1,2,…,n; aij ≤ 10000.

Kết quả: đưa ra file văn bản NZTABLE.OUT gồm n dòng, dòng thứ i ghi n số nguyên dương bi1, bi2, …, bin là các số trên dòng thứ i của bảng B.

Hai số liên tiếp trên cùng một dòng được ghi cách nhau bởi một dấu cách.



Ví dụ:

NZTABLE.INP

4

1 0 3 0


4 0 0 5

0 0 6 0


0 0 0 0

NZTABLE.OUT

1 3 3 5

4 4 6 5


4 6 6 6

4 0 6 5


Lời giải:

Ta xây dựng mảng b giống như định nghĩa của đề bài như đoạn chương trình sau:

if (a[i,j]>0) then b:=a[i,j] else {biển b chỉ phần tử bij. Nếu aij > 0 thì bij = aij}

begin


b:=-maxlongint; {gán bij=-∞ vì ta cần giá trị bij lớn nhất}

kc:=maxlongint; {kc là biến lưu khoảng cách, gán bằng ∞

vì ta cần giá trị nhỏ nhất}

for p:=1 to n do {duyệt qua các ô trên cột j}

if (a[p,j]<>0) then {chỉ xét các ô có giá trị khác 0}

if ((abs(i-p)

((abs(i-p)=kc) and (a[p,j]>b))) {có khoảng cách bằng nhưng giá trị lớn hơn}

then


begin

kc:=abs(i-p); {cập nhật lại khoảng cách}

b:=a[p,j]; {cập nhật lại bij}

end;


for p:=1 to n do {duyệt qua các ô trên dòng i}

... {thực hiện tương tự}

if (kc=maxlongint) then b:=0; {nếu tất cả các phần tử của dòng i, cột j

đều bằng 0 thì bij=0}

end;

write(b,' '); {in bij ra màn hình}



Chương trình:

const MAXN=55;

finp='NZTABLE.INP';

fout='NZTABLE.OUT';

var i, j, b, n, kc, p: longint;

a: array[1..MAXN, 1..MAXN] of longint;

begin

assign(input, finp);



reset(input);

assign(output, fout);

rewrite(output);

readln(n);

for i:=1 to n do

for j:=1 to n do

read(a[i,j]);

for i:=1 to n do

begin

for j:=1 to n do



begin

if (a[i,j]>0) then b:=a[i,j] else

begin

b:=-maxlongint;



kc:=maxlongint;

for p:=1 to n do

if (a[p,j]<>0) then

if ((abs(i-p)b))) then

begin

kc:=abs(i-p);



b:=a[p,j];

end;


for p:=1 to n do

if (a[i,p]<>0) then

if ((abs(j-p)b))) then

begin


kc:=abs(j-p);

b:=a[i,p];

end;

if (kc=maxlongint) then b:=0;



end;

write(b,' ');

end;

writeln;


end;

close(input);

close(output);

end.


Bài 4: Tìm mật khẩu

Việc bảo vệ máy tính của mình để hạn chế người khác thâm nhập vào là một vấn đề đặt ra cho mọi nguời sử dụng máy tính. Để tăng tính an toàn trong lưu trữ, một nguời đã quyết định dấu mật khẩu truy cập máy tính của mình vào một xâu T với một quy ước sao cho khi cần anh ta có thể lấy lại đuợc mật khẩu từ T như sau.

Là một người yêu thích số học anh ta thường chọn mật khẩu P là một số nguyên tố và đem dấu vào một xâu ký tự T sao cho P chính là số nguyên tố có giá trị lớn nhất trong số các số nguyên tố tạo được từ các xâu con của T (xâu con của một xâu ký tự T là một chuỗi liên tiếp các ký tự trong T).

Ví dụ: xâu T=”Test1234#password5426” chứa mật khẩu là 23 vì T chứa các xâu con ứng với các số nguyên tố 2,3,23 và 5.



Yêu cầu: Cho một xâu ký tự T chiều dài không quá 250 ký tự. Tìm mật khẩu P đã dấu trong xâu T biết P có giá trị nhỏ hơn 105. Dữ liệu cho đảm bảo T chứa ít nhất 1 số nguyên tố.

Dữ liệu: Vào từ file văn bản PASSWORD.INP gồm 1 dòng duy nhất là xâu T.

Kết quả: Ghi ra file văn bản PASSWORD.OUT chứa số P tìm được.

Ví dụ:

PASSWORD.INP

Test1234#password5426

PASSWORD.OUT

23

Lời giải:

Ta duyệt qua tất cả các xâu con của xâu T mà có thể tạo thành một số và kiểm tra số đó có phải số nguyên tố hay không.

Để duyệt qua các xâu con, ta duyệt qua vị trí đầu:

for i:=1 to length(t) do {i là vị trí đầu của xâu con}

Với mỗi vị trí đầu i, ta duyệt qua vị trí cuối của xâu con:

j:=i;


while (j<=length(t)) do

begin


...

inc(j);


end;

Có hai điều kiện để ta dừng quá trình duyệt một xâu con với vị trí đầu là i:



  • Gặp một ký tự không phải chữ số:

if (t[j]<'1') or (t[j]>'9') then break;

  • Số tạo thành lớn hơn hoặc bằng 105, vì đề bài đã nêu rõ P có giá trị nhỏ hơn 105:

if v>=100000 then break;

Khi đọc được một chữ số mới, ta nhân số hiện tại với 10 rồi cộng thêm chữ số mới:

v:=v*10+ord(t[j])-ord('0');

Nếu số thu được là số nguyên tố và lớn hơn kết quả tốt nhất tìm được thì cập nhật kết quả:

if nguyento(v) then

if (v>kq) then kq:=v;



Chương trình:

const finp='password.inp';

fout='password.out';

function nguyento(n: longint): boolean;

var i: longint;

begin


nguyento:=false;

if n<2 then exit;

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

if (n mod i = 0) then

exit;

nguyento:=true;



end;

var t: string;

i, kq, v, j: longint;

begin


assign(input,finp);

reset(input);

assign(output,fout);

rewrite(output);

readln(t);

kq:=-1;


for i:=1 to length(t) do

begin


v:=0;

j:=i;


while (j<=length(t)) do

begin


if (t[j]<'1') or (t[j]>'9') then break;

v:=v*10+ord(t[j])-ord('0');

if v>=100000 then break;

writeln(v);

if nguyento(v) then

if (v>kq) then kq:=v;

inc(j);

end;


end;

writeln(kq);

close(input);

close(output);



end.


Каталог: UserFiles -> HEAD393 -> news -> attachment
UserFiles -> PHƯƠng pháp viết nghiên cứu khoa họC Ứng dụng sư phạM
UserFiles -> 29 Thủ tục công nhận tuyến du lịch cộng đồng
UserFiles -> BÀi phát biểu củA ĐẠi diện sinh viên nhà trưỜng sv nguyễn Thị Trang Lớp K56ktb
UserFiles -> BỘ XÂy dựNG
UserFiles -> CỘng hòa xã HỘi chủ nghĩa việt nam độc lập – Tự do – Hạnh phúc
UserFiles -> BỘ XÂy dựng số: 10/2013/tt-bxd cộng hoà XÃ HỘi chủ nghĩa việt nam
UserFiles -> CỘng hòa xã HỘi chủ nghĩa việt nam kho bạc nhà NƯỚC Độc lập Tự do Hạnh phúc
UserFiles -> MÔn toán bài 1: Tính a) (28,7 + 34,5) X 2,4 b) 28,7 + 34,5 X 2,4 Bài 2: Bài toán
UserFiles -> CỦa bộ trưỞng bộ VĂn hóa thông tin về việc thành lập tạp chí di sản văn hóa thuộc cục bảo tồn bảo tàng bộ trưỞng bộ VĂn hóa thông tin
attachment -> PHÂn công trực nội trú Từ 01/09/2014 đến hết 30/09/2014

tải về 440.12 Kb.

Chia sẻ với bạn bè của bạn:
1   2   3   4




Cơ sở dữ liệu được bảo vệ bởi bản quyền ©hocday.com 2024
được sử dụng cho việc quản lý

    Quê hương