01/10/2018, 09:56
Bài toán mã đi tuần
Đọc trên mạng thì em thấy có thuật toán mã đi tuần, xem code thì em thấy khá dài, em biến tấu một chút theo ý mình thì em thấy nó chạy hình như không bao giờ dừng, em nghĩ mãi mà không biết đã sai chỗ nào ạ!!!
program gin;
uses crt;
const
h : array[1..8] of Integer = (2, 1, -1, -2, -2, -1, 1, 2);
c : array[1..8] of Integer = (1, 2, 2, 1, -1, -2, -2, -1);
var
t, i, j, cot, hang : Integer;
a : array[1..100, 1..100] of Integer;
kt : array[-2..11, -2..11] of Boolean;
procedure print;
var
i : Integer;
begin
for i := 1 to 8 do
begin
for j := 1 to 8 do write(a[i, j],' ');
writeln;
end;
halt;
end;
procedure try(i, j : Integer);
var
g : Integer;
begin
a[i, j] := t;
// writeln(t);
if t = 64 then print
else
for g := 1 to 8 do if kt[i + h[g], j+ c[g]] then
begin
kt[i, j] := false;
inc(t);
try(i + h[g], j + c[g]);
kt[i, j] := true;
dec(t);
end;
end;
begin
write('Nhap toa do : ');
read(hang, cot);
t := 1;
for i:= low(kt) to high(kt) do
for j := low(kt[i]) to high(kt[i]) do
kt[i, j] := false;
for i:=1 to 8 do
for j:=1 to 8 do
kt[i, j] := true;
try(hang, cot);
end.
Bài liên quan
Biến tấu làm gì…
Hàm low, high là cái gì thế, lần đầu mình thấy luôn :v
Bạn debug thử bằng cách thêm
writeln(i, ' ', j)
để xem bạn đã duyệt qua các trạng thái nào.Mà để mảng 5x5 debug cho dễ, 8x8 hơi khó quan sát.
UPD: Đã nhìn thấy lỗi. Phải gán
kt[i+h[g], j+c[g]] = false
, nếu không chỉ sau 2 trạng thái nó sẽ quay về trạng thái cũ.VD: Từ
i, j
->i+1, j+2
->i, j
-> … -> lặp vô hạnMục đích của quay lui là quay cái trạng thái đích (là i+h[g], j+c[g]) kia. Còn trạng thái của i, j phải được gán ở đầu hàm, tức là
Kia là mã giả thôi. Mà nói thật là chả ai đi code ngược đời như bạn, bình thường ô đã duyệt được gán là true, chưa duyệt là false; thế mà bạn gán ngược lại :v
Biến tấu cho hiểu rõ chứ anh
https://www.freepascal.org/docs-html/rtl/system/low.html
https://www.freepascal.org/docs-html/rtl/system/high.html
Tại em quen tay rồi, từ trước giờ cứ cái nào đã duyệt qua thì false
Đậu, đừng có mà chưa hiểu code đã biến tấu rồi :v Nhiều code đúng sau khi biến tấu đã trở thành code không thể debug nổi :v
Hàm low và high dùng làm gì, đừng nghịch dại. Tốt nhất là bỏ đi plz. Các chỉ số của hàm kt không chạy quá 0…n được đâu.
-> Nói luôn: thêm điều kiện
i+h[g]
vàj+c[g]
nằm trong khoảng duyệt được (tức là từ 0…n-1 hoặc 1…n), điều này rất quan trọng.Đừng quen dại -_- sau này nhiều bài toán khác phải xác định rõ ràng trạng thái true và false, không phải cứ gán bừa là được. Quen tay kiểu này có ngày debug code đến vỡ mồm :v
Là sao anh, nói rõ được không ạ
Em làm một số trường hợp đúng còn một số trường hợp nó như này
Không tìm thấy số 1 mà có lận 2 số 27 luôn!!
Rõ ràng là
i+h[g], j+c[g]
là trạng thái sau củai, j
còn gì. Mà trạng thái sau bắt buộc phải truy cập được chứ.i, j
truy cập được <->1 <= i, j <= 8
->
i+h[g], j+c[g]
truy cập được <->1 <= i+h[g], j+c[g] <= 8
2 số 27 là do có 1 số 27 khác đè vào số 1. Mà trường hợp như vậy xảy ra là do code sai!
UPD: Không thấy số 1 là do ô
hang, cot
không gánkt[hang, cot]
đã duyệt. Ôhang, cot
là ô đầu tiên và bắt buộc phải duyệt từ đầu, nên phải gánkt[hang, cot] = true
, tức là đã duyệt.Khi em làm vậy thì nó lại lặp vô hạn như ban đầu
Gán bằng true nếu như bạn coi true là đã duyệt…
Mình tạm coi true là đã duyệt.
Mã giả:
Mình cũng hay code kiểu TRUE là chưa duyệt vì
If kt[i] then...
có vẻ thuận tay hơn :vChủ thread dính vô hạn có lẽ do để mã chạy quá khỏi bàn cờ đấy
Dính vô hạn vì 2 nguyên nhân:
i, j
vài + 2, j + 1
.Thớt nên đặt tên hằng số để tránh những vấn đề ntn và cho người khác dễ đọc code.