首先,字母在网格中的位置很容易计算:
function get_pos( c : char)
begin
int col ← (c-'A') modulo 4
int row ← (c-'A') div 4
return (row,col)
end
假设位置 (6,2) 和 (6,3) 可以使用
我们可以简单地将单元坐标之间的减法定义为:
function subtract( pos1, pos2 : position )
begin
return (pos2.row-pos1.row, pos2.col-pos1.col)
end
如果减法产生一对 (x,y),则路径只是 x 乘以字符“R”(如果 x 为正)或“L”(如果 x 为负),如果 x 为零,则可能什么都没有,类似地,y 乘以字符 'D ' 如果 y 是正数,或者 'U' 如果 y 是负数,如果 y 为零,则可能什么都没有,那么我们以字符 'E' 结尾。
function print_row_path( pos1, pos2 : position )
begin
path ← subtract(pos1,pos2)
if path.row > 0 then
print_times_char(path.row,'R')
else if path.row < 0
print_times_char(-path.row,'L')
end if
end
function print_col_path( pos1, pos2 : position )
begin
path ← subtract(pos1,pos2)
if path.col > 0 then
print_times_char(path.col,'D')
else if path.col < 0
print_times_char(-path.col,'U')
end if
end
function print_path_direction( pos1, pos2 : position ; first_direction : direction )
begin
if (first_direction = FIRST_MOVE_ROW) then
print_row_path(pos1,pos2)
print_col_path(pos1,pos2)
else
print_col_path(pos1,pos2)
print_row_path(pos1,pos2)
end if
print 'E'
end
function print_path(start, end : char)
begin
position pos1 ← get_pos(start)
position pos2 ← get_pos(end)
print_path_direction(pos1,pos2, FIRST_MOVE_ROW)
end
其中 print_times_char(t,c) 是打印 t 次字符 c 的函数。我定义了路径打印的两种“风格”,一种先打印行移动,另一种先打印列移动。
假设位置 (6,2) 和 (6,3) 被禁止
如果我们不允许使用位置 (6,2) 和 (6,3),那么:
- 如果 'A' ≤ start,end ≤ 'X' 或 'Y' ≤ start,end ≤ 'Z' : (6,2) 或 (6.3) 将永远不会在路径中使用
- if 'A' ≤ start ≤ 'X' and 'Y' ≤ end ≤ 'Z' :确保不使用禁止单元格首先打印列移动
- if 'A' ≤ end ≤ 'X' and 'Y' ≤ start ≤ 'Z' : 这次我们必须先打印行移动
在伪代码中:
function print_path_wo_forbidden(start, end : char)
begin
position pos1 ← get_pos(start)
position pos2 ← get_pos(end)
if if 'A' ≤ start ≤ 'X' and 'Y' ≤ end ≤ 'Z' then
print_path_direction(pos1,pos2, FIRST_MOVE_COLUMN)
else
print_path_direction(pos1,pos2, FIRST_MOVE_COLUMN)
end if
end
复杂
打印两个位置之间的路径显然在 O(1) 中,因此对于长度为 n 的字符串,我们可以构建一个 O(n) 算法。