Mô típ các bài toán phủ gạch chữ L
Công Hiệp
Các bài toán loại lát nền bằng những viên gạch thước thợ khá quen thuộc đối với mỗi
chúng ta. Nó từng được nhắc tới khá nhiều trong tạp chí và trong các kỳ thi HSG. Cùng
với một số bài mang tính tham khảo thêm, tôi muốn cùng các bạn tổ hợp lại những bài tập
tin nhưng mang đậm tính suy luận toán học này.
Trước hết, hãy xét bài toán cơ sở:
I. Bài toán 1: Hãy phủ kín một nền nhà hình chữ nhật kích thước M*N (M, N ≥ 3) bằng
những viên gạch thước thợ (hình chữ L, chiếm 3 ô vuông đơn vị) hoặc thông báo là không
thể làm được điều đó.
Dữ liệu: Đọc từ màn hình kích thước M N
Kết quả: Xuất ra file PHUCHU_L.OUT -1 nếu không tồn tại cách phủ, ngược lại in ra ma
trận số biểu hiện cách phủ, trong đó cứ 3 số giống nhau tạo miền liên thông hình chữ L thể
hiện một viên gạch
Ví dụ: M = 3 và N = 4
Cơ sở thuật toán: Dễ thấy rằng nếu cả hai chỉ số kích thước của bảng M, N đều không
chia hết cho 3 thì bài toán vô nghiệm, bởi khi đó M*N không chia hết cho 3 trong khi đó,
số ô mà các viên gạch phủ được lại luôn chia hết cho 3. Trong các trường hợp ngựơc lại,
không mất tính tổng quát ta giả sử M (số dòng) chia hết cho 3 (nếu N chia hết cho 3 thì ta
lại đảo cạnh). Ta tách hai trường hợp:
Nếu N là số chẵn, đặt N = 2k. Ta hoàn toàn có thể làm tương tự như trường hợp 3*4 ở trên,
2 viên gạch đặt chồng lên nhau sẽ phủ kín hình chữ nhật 3*2 -> ghép những viên gạch này
ta sẽ có được hình chữ nhật kích thước M*N tuỳ ý (với M = 3q và N = 2k).
Trong trường hợp N là số lẻ, dễ thấy N -3 là số chẵn => ta đã phủ được hình chữ nhật M *
(N-3) như cách làm trên. Vấn đề còn lại là phủ nốt hình chữ nhật kích thước M*3 (3 cột
cuối cùng). Dễ thấy nếu M chia hết cho 2 thì ta lại quay chỉ số 3 làm dòng và M là số cột,
ta sẽ phủ nốt hình chữ nhật kích thước 3*M này => bài toán có nghiệm, trong trường hợp
ngược lại (M lẻ), bài toán vô nghiệm.
Ví dụ: M = 6, N = 5
Chương trình cài đặt như sau:
Uses crt;
Const
fo = ′phuchu_l.out ′;
Var
a : array [1..150, 1..150] of integer;
m, n, sl : integer;
f : text;
Procedure Init;
Begin
clrscr;
write( ′Nhap kich thuoc m, n : ′);
readln(m, n);
End;
Procedure error;
Begin
write( ′KHONG THE XEP DUOC! ′);
readln;
halt;
End;
Procedure Check;
Begin
if m * n mod 3 <> 0 then error;
sl := 0;
End;
Procedure xep3(m, n : integer);
Var
sl1, i : integer;
Begin
if m mod 2 <> 0 then error;
sl1 := sl;
for i := 1 to m do
begin
if i mod 2 = 1 then inc(sl, 2);
a[i, n - 2] := sl;
a[i, n] := sl + 1;
if i mod 2 = 1 then a[i, n - 1] := sl + 1
else a[i, n - 1] := sl;
end;
End;
Procedure xep(m, n : integer);
Var
c, i, sl1 : integer;
Begin
c := 1;
while (c < n)and(c<>n - 2) do
begin
sl1 := sl;
for i := 1 to m do
begin
if i mod 3 = 1 then inc(sl);
if i mod 3 = 0 then inc(sl);
a[i, c] := sl;
end;
inc(c); sl := sl1;
for i := 1 to m do
begin
if i mod 3 = 1 then inc(sl);
if i mod 3 = 2 then inc(sl);
a[i, c] := sl;
end;
inc(c);
end;
if c = n - 2 then xep3(m, n); {xet rieng 3 cot cuoi}
End;
Procedure Print;
Var
i, j, k : integer;
Begin
assign(f, fo);rewrite(f);
if m mod 3 = 0 then
for i := 1 to m do
begin
for j := 1 to n do
begin
textbackground((a[i, j] mod 7));
if (m <= 15) and (n <= 15) then write(a[i, j] : 4);
write(f, a[i, j] : 5);
textbackground(black);
end;
writeln; writeln(f);
end
else
for j := 1 to m do
begin
for i := 1 to n do
begin
textbackground((a[i, j] mod 7));
if (m <= 15) and (n <= 15) then write(a[i, j] : 4);
write(f, a[i, j] : 5);
textbackground(black);
end;
writeln;writeln(f);
end;
close(f);
writeln( ′Moi mo tep phuchu_l.out xem ′);
readln
End;
Begin
Init;
check;
if m mod 3 = 0 then xep(m, n)
else xep(n, m);
Print;
End.
II. Bài toán 2:
Hãy phủ một nền nhà hình vuông kích 2
N
* 2
N
(N ≤ 7) bằng những viên gạch thước thợ sao
cho còn lại đúng một ô tại vị trí (x, y) cho trước (lỗ thoát nước).
Dữ liệu: Đọc từ màn hình N
Kết quả: Xuất ra file LATCHU_L.OUT -1 nếu không tồn tại cách phủ, ngược lại in ra ma
trận số biểu hiện cách phủ, trong đó cứ 3 số giống nhau tạo miền liên thông hình chữ L thể
hiện một viên gạch Dấu X thể hiện lỗ thoát nước.
Ví dụ: N = 2, X = 2, Y = 2 ta có vídụ về một cách xếp thoả mãn như sau:
Trước hết ta khẳng định bài toán luôn có nghiệm, để chứng minh ta dùng công cụ rất mạnh
từ toán, nếu như chúng ta chứng minh được tính đúng đắn luôn có nghiệm của bài toán thì
cũng là chúng ta đã giải quyết được 80%, vấn đề còn lại chỉ là 20% lập trình. Thật vậy, ta
chứng minh bài toán bằng phương pháp qui nạp, từ đó các bạn sẽ thấy việc cài đặt là rất
đơn giản:
Với N = 1, hình vuông kích thước 2*2, khi đó ta luôn lát được bởi chỉ có thể là 1 trong 4
trường hợp sau:
Giả sử ta đã chứng minh bài toán đúng với N = K (K> 1), vấn đề còn lại là bài toán phải
đúng với N = K+1. Với hình vuông 2
K+1
* 2
K+1
ta hãy chia thành 4 hình vuông con kích
thước 2
K
* 2
K
, đánh số từ 1 đến 4. Không mất tính tổng quát, giả sử lỗ thoát nước ở hình
vuông I, khi đó hình vuông I bị mất một ô và theo giả sử N đúng tới K thì hình vuông này
có cách phủ kín. Đối với 3 hình vuông còn lại, vấn đề làm cho chúng cùng mất đi một hình
vuông đơn vị là rất đơn giản, ta hãy lát một viên gạch vào chính giữa sao cho, 3 ô của nó
nằm trên 3 hình vuông còn lại này → các hình vuông kích thước 2
K
* 2
K
đều được phủ kín
↔hình vuông 2
k+1
* 2
K+1
cũng được phủ kín , minh hoạ như sau:
Như vậy ta đã chứng minh bài toán đúng đắn với mọi N. Việc cài đặt bài toán này chúng ta
có thể dùng phép đệ qui (chú ý rằng N ≤ 7 nên phương pháp đệ qui hoàn toàn khả thi). Do
đệ qui không có quay lui nên thời gian chạy chương trình là không đáng kể.
III. Bài toán 3:
Tôi xin được mở rộng tiếp bài toán lát nền mà trong số báo vui xuân Tân Tỵ, PGS-TS
Nguyễn Xuân Huy đã đề cập tới. Bài toán được phát biểu lại như sau: Cần phải lát kín một
nền nhà kích thước N*N với N = 2
K
bằng những viên gạch thước thợ. Sao cho:
Nền nhà còn thừa đúng một ô tại vị trí (x, y) Hai viện gạch chung cạnh phải khác màu nhau
Số màu phải dùng là ít nhất. Dữ liệu: Trong file văn bản LATNEN.INP gồm một dòng duy
nhất chứa 3 số tự nhiên N, X, Y (N ≤ 128).
Kết quả: Ra file văn bản LATNEN.OUT gồm
Dòng đầu là số màu ít nhất cần dùng. Tiếp đó là một phương án lát nền tìm được trong đó
cứ mỗi viên gạch được biểu diễn bởi 3 số giống nhau tạo hình viên gạch và hiển thị mầu
của viên gạch đó (ví dụ). Ô có toạ độ (x, y) ghi chữ ′X ′ thể hiện lỗ thoát nước.
Nhận xét: với N = 2 thì cần 1 mầu còn với mọi N > 2 ta cần tối đa 3 mầu (xem thêm số báo
xuân Tân Tỵ để biết thêm chi tiết phần lập luận)
Cách giải: Khởi tạo, ta hãy khởi tạo giá trị cho một hình vuông 2*2, ba hình vuông bên
trong nhận giá trị 1, hình vuông trên phải nhận giá trị 2 sau đó ta sẽ thực hiện các phép
biến hình sau: