TỦ SÁch tri thức duy tân nguyễn xuân huy sáng tạo trong thuật toán và LẬp trìNH



tải về 2.51 Mb.
trang14/21
Chuyển đổi dữ liệu24.07.2016
Kích2.51 Mb.
#3874
1   ...   10   11   12   13   14   15   16   17   ...   21

5.3 Cắt hình


Việt Nam, 2008

Một tấm bìa dạng lưới vuông cạnh dài n = 2k tạo bởi các ô vuông đơn vị đánh số theo dòng 1.. n tính từ trên xuống và theo cột 1..n tính từ trái sang. Người ta thực hiện lần lượt hai thao tác đan xen nhau sau đây cho đến khi nhận được một cột gồm n2 ô vuông đơn vị:

1. Cắt ngang hình theo đường kẻ giữa sau đó chồng nửa trên lên trên nửa dưới;

2. Cắt dọc hình theo đường kẻ giữa sau đó chồng nửa trái lên trên nửa phải.

Tại cột cuối cùng người ta đánh số các ô vuông đơn vị 1, 2,..., n2 tính từ trên xuống.

Hãy viết hai thủ tục sau đây

a) ViTri(k, i, j) = v cho ra số thứ tự v của ô (i,j) trên cột cuối cùng.

b) ToaDo(k, v, i, j) Cho trước k và vị trí v trên cột cuối cùng, tính tọa độ (i,j) của ô ban đầu.

Thí dụ

ViTri(2, 4, 3) = 8.

ToaDo(2,8,i, j) cho kết quả i = 4, j = 3.
Thuật toán
Ta khảo sát bài toán với k = 2. Ta có n = 2k = 22 = 4. Ta kí hiệu ô nằm trên dòng i, cột j là [i,j].

A

C


Tầng 1

[1,1] [1,2] [1,3] [1,4]

[2,1] [2,2] [2,3] [2,4]

[3,1] [3,2] [3,3] [3,4]

[4,1] [4,2] [4,3] [4,4]


B

D


4 mảnh thu được sau một lần ND




Trước khi cắt cột có duy nhất 1 tầng
Nhận xét: Ta gọi một lần cắt ngang và một lần cắt dọc liên tiếp nhau là ND. Sau mỗi lần ND ta thu được 4 mảnh vuông và bằng nhau A, B, C và D được chồng lên nhau thành một cột theo thứ tự tính từ trên xuống là A, B, C và D (mảnh A trên cùng, mảnh D dưới cùng). Gọi d là độ dày (số tầng) của khối này. Ta có, lúc đầu d = 1 và cột chỉ có 1 tầng gồm 1 tấm bìa duy nhất ban đầu. Gọi n là chiều dài cạnh của một mảnh hình vuông. Sau mỗi lần ND, n giảm 2 lần. Vị trí v của các ô đơn vị trong mảnh A sẽ được bảo lưu, trong mảnh B được cộng thêm d, mảnh C được cộng thêm 2d và mảnh D được cộng thêm 3d. Sau mỗi lần ND số tầng d sẽ tăng thêm 4 lần. Biết tọa độ (i,j) trong hình ABCD ta dễ dàng tính được tọa độ mới (i',j') trong từng mảnh.

Tầng 1

[1,1] [1,2] [1,3] [1,4]

[2,1] [2,2] [2,3] [2,4]

AC


Tầng 1: A

[1,1] [1,2]

[2,1] [2,2]



Tầng 2: B

[3,1] [3,2]

[4,1] [4,2]


Tầng 2

[3,1] [3,2] [3,3] [3,4]

[4,1] [4,2] [4,3] [4,4]

BD


Tầng 3: C

[1,3] [1,4]

[2,3] [2,4]



Tầng 4: D

[3,3] [3,4]

[4,3] [4,4]



Cắt ngang lần 1 và chồng nửa trên lên trên nửa dưới thu được 2 tầng

Cắt dọc lần 1 và chồng nửa trái lên trên nửa phải thu được 4 tầng



















Tầng 1

[1,1] [1,2]




Tầng 1

[1,1]

Tầng 2

[3,1] [3,2]




Tầng 2

[3,1]

Tầng 3

[1,3] [1,4]




Tầng 3

[1,3]

Tầng 4

[3,3] [3,4]




Tầng 4

[3,3]

Tầng 5

[2,1] [2,2]




Tầng 5

[2,1]

Tầng 6

[4,1] [4,2]




Tầng 6

[4,1]

Tầng 7

[2,3] [2,4]




Tầng 7

[2,3]

Tầng 8

[4,3] [4,4]




Tầng 8

[4,3]










Tầng 9

[1,2]

Cắt ngang lần 2 và chồng nửa trên lên trên nửa dưới thu được 8 tầng




Tầng 10

[3,2]




Tầng 11

[1,4]




Tầng 12

[3,4]










Tầng 13

[2,2]










Tầng 14

[4,2]










Tầng 15

[2,4]










Tầng 16

[4,4]

























Cắt dọc lần 2 và chồng nửa trái lên trên nửa phải

Ta chọn cách mã số các mảnh A, B, C và D một cách khôn ngoan. Cụ thể là ta gán mã số cho các mảnh này theo số lần cộng thêm độ dày d sau mỗi lần ND, tức là ta đặt A = 0, B = 1, C = 2 và D = 3. Trong dạng nhị phân ta có A = 002, B = 012, C = 102 và D = 112.



A

002 = 0


C

102 = 2


B

012 = 1


D

112 = 3



Sau mỗi lần ND ta thu được 4 mảnh A, B, C, D.

function ViTri(k,i,j: integer): integer;

var d, v, m, manh, n: integer;

begin

d := 1; { so tang }

v := 1; { tang chua o [i,j] }

n := 1 shl k; { n = 2^k }

for m := 1 to k do

begin

n := n div 2; manh := 0;

if (j > n) then

begin

manh := 2; j := j - n;

end;

if (i > n) then

begin

manh := manh + 1; i := i - n;

end;

v := v + manh*d; d := 4*d;

end;

ViTri := v;

end;
Thủ tục ToaDo là đối xứng với thủ tục ViTri.
procedure ToaDo(k,v: integer; var i,j: integer);

var n,nn,m,d, manh: integer;

begin

n := 1 shl k; d := n*n;

n := 1 ; { kich thuoc 1 tang }

i := 1; j := 1;

for m := 1 to k do

begin

d := d div 4;

manh := (v-1) div d;

if (manh >= 2) then j := j+n;

if odd(manh) then i := i+n;

v := v - manh*d; n := n * 2;

end;

end;
// DevC++

#include

using namespace std;

// P R O T O T Y P E S

int ViTri(int, int, int);

void ToaDo(int, int, int &, int &);

void Test(int);

// I M P L E M E N T A T I O N

int main() {

Test(2);

cout << endl;

system("PAUSE");

return EXIT_SUCCESS;

}

// Cho biet k va toa do (i,j). Tim vi tri tren cot

int ViTri(int k, int i, int j) {

int n = 1 << k; // kich thuoc hinh: n = 2^k

int d = 1; // be day 1 tang

int v = 1; // vi tri;

int manh;

for (int m = 0; m < k; ++m) {

n >>=1; // n = n/2

manh = 0;

if (j > n) { manh = 2; j -= n; }

if (i > n) { manh += 1; i -= n; }

v += manh * d; d *= 4;

}

return v;

}

// Cho vi tri o tren cot v, tinh toa do (i,j). n = 2^k

void ToaDo(int k, int v, int &i, int &j) {

int n = 1, d = 1 << k, manh = 0;

d *= d;

i = j = 1;

for (int m = 0; m < k; ++m) {

d >>= 2; // d /= 4;

manh = (v - 1) / d;

if (manh >= 2) j += n;

if (manh % 2 == 1) i += n;

v -= manh * d; n *= 2;

}

}
Độ phức tạp

Với n = 2k chương trình cần k lần lặp, mỗi lần lặp cần thực hiện không quá 10 phép toán số học trên các số nguyên.

Thủ tục Test dưới đây hiển thị vị trí v của mọi ô (i,j), i = 1..n, j = 1..n sau đó xuất phát từ vị trí v để tính lại tọa độ i, j.

(* Pascal *)

procedure Test(k: integer);

var n, v, ii, jj : integer;

begin

n := 1 shl k; { n = 2^k }

writeln; writeln( ' k = ', k, ' n = ', n);

for i := 1 to n do

for j := 1 to n do

begin

v := ViTri(k, i, j); ToaDo(k, v, ii, jj);

writeln; write('(',i, ',', j, ') => ', v);

writeln(' => ', '(', ii, ',', jj, ')');

readln;

end;

end;
// DevC++

void Test(int k) {

int n = 1 << k;

cout << endl << "k = " << k << " n = " << n

int v, ii, jj;

for (int i = 1; i <= n; ++i)

for (int j = 1; j <= n; ++j) {

v = ViTri(k, i, j); ToaDo(k, v, ii, jj);

cout << endl << "(" << i << "," << j << ") => "

<< v << " => (" << ii << "," << jj << ")";

cin.get();

}

}


Каталог: tailieu
tailieu -> MỘt số thủ thuật khi sử DỤng phần mềm adobe presenter tạo bài giảng e-learning
tailieu -> Trung tâM ĐÀo tạo mạng máy tính nhất nghệ 105 Bà Huyện Thanh Quan – 205 Võ Thị Sáu, Q3, tp. Hcm
tailieu -> Céng hßa x· héi chñ nghÜa viÖt nam Độc lập tự do hạnh phúc
tailieu -> Lê Xuân Biểu giao thông vận tảI ĐẮk lắK 110 NĂm xây dựng và phát triểN (1904 2014) nhà xuất bảN giao thông vận tảI
tailieu -> ĐỀ thi học sinh giỏi tỉnh hải dưƠng môn Toán lớp 9 (2003 2004) (Thời gian : 150 phút) Bài 1
tailieu -> A. ĐẠi số TỔ HỢp I. Kiến thức cơ bản quy tắc cộng
tailieu -> Wikipedia luôn có mặt mỗi khi bạn cần giờ đây Wikipedia cần bạn giúp
tailieu -> CHÍnh phủ CỘng hòa xã HỘi chủ nghĩa việt nam độc lập Tự do Hạnh phúc
tailieu -> VĂn phòng cộng hoà XÃ HỘi chủ nghĩa việt nam

tải về 2.51 Mb.

Chia sẻ với bạn bè của bạn:
1   ...   10   11   12   13   14   15   16   17   ...   21




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