{$A+,B-,D+,E+,F-,G-,I+,L+,N-,O+,P-,Q-,R+,S+,T-,V+,X+,Y+} {$M 16384,0,655360} { Задача 5. Даны обозначения двух полей шахматной доски (например, A5 и C2). Найти минимальное число ходов, которые нужны шахматному коню для перехода с первого поля на второе. Идея решения : ОЧЕРЕДЬ возможных ходов коня Помещаем в очередь исходное поле коня Пока ( не нашли ) Выбираем из очереди первый элемент - клетку X,Y Если это элемент НЕ искомый то Клетки, достижимые из X,Y за ход коня если не конечные и еще не помеченные помещаем в очередь и помечаем } var Que : array [1..64,1..3] of integer; { Очередь ходов } Marked : array [1.. 8,1..8] of boolean; { Пометки на доске} StartCell, EndCell : string; { Начальные и конечная позиции - строковые} Sx,Sy,Ex,Ey, { - числовые } x,y, { Текущая позиция} StepNumber, { Номер хода} QueBegin, QueEnd : integer; { Начало и конец очереди} Found : boolean; procedure Convert(Cell:string; var x,y:integer); { Перевод позиции } var { коня от строкового } c : char; { представления к } s : string; { числовому } i : integer; begin c := Cell[1]; x := ord(c) - 96; { Вместо a-h - 1-8 } s := copy(Cell,2,1); val(S,y,i); { Вместо '1'-'8' - 1-8} end; procedure Put(x,y,StepNumber:integer); {Занести в очередь} begin Inc(QueEnd); { увеличить количество } Que[QueEnd,1] := x; { координата по x } Que[QueEnd,2] := y; { координата по y } Que[QueEnd,3] := StepNumber; { номер хода } Marked[x,y] := true; { Помечаем использованную} end; procedure Get(var x,y,StepNumber:integer); { Взять из очереди } begin x := Que[QueBegin,1]; { координата по x } y := Que[QueBegin,2]; { координата по y } StepNumber := Que[QueBegin,3]; { номер хода } Inc(QueBegin); { изменить начало } end; procedure StartProcess; var i,j : integer; begin readln(StartCell); { Читаем начальную позицию} readln( EndCell); { Читаем конечную позицию} Convert(StartCell,Sx,Sy); { Преобразовать к числам } Convert(EndCell, Ex,Ey); { Преобразовать к числам } QueBegin := 1; { Начало очереди } QueEnd :=0; { Конец очереди } for i:= 1 to 8 do { Все клетки } for j:= 1 to 8 do Marked[i,j] := false; { непомечены } Put(Sx,Sy,0); { Начальную позицию в очередь } Marked[Sx,Sy] := true; { Помечаем начальную позицию} end; procedure PutAll(x,y,StepNumber:integer;var Found:boolean); {Занести в очередь} type {все текущие возможные ходы} Knight = array [1..8,1..2] of integer; {Возможные ходы коня} const Steps : Knight = (( 1,-2),( 1, 2), {Массив констант} (-1,-2),(-1, 2), ( 2,-1),( 2, 1), (-2,-1),(-2, 1) ); var i, CurrentX, CurrentY : integer; begin Found := False; {Нашли конечную клетку} i:=0; {номер возможного хода} while (not Found) and (i<8) do {Пока не нашли и есть ход} begin {Делаем следующий ход } inc(i); CurrentX := x+steps[i,1] ; {X текущего хода } CurrentY := y+steps[i,2] ; {Y текущего хода } Found := (Ex=CurrentX) and (Ey=CurrentY); {это искомая клетка?} if not Found and { Если нет и } (CurrentX>0) and (CurrentX<9) and { X на доске и } (CurrentY>0) and (CurrentY<9) and { Y на доске и } not Marked[CurrentX,CurrentY] { поле (X,Y) не помечено} then Put(CurrentX,CurrentY,StepNumber); {помещаем в очередь и помечаем} end; end; begin StartProcess; { Начало работы } StepNumber:=0; { Количество шагов - 0 } Found := (Sx=Ex) and (Sy=Ey); { Признак завершения работы} while (not Found) do { Пока не нашли } begin { } Get(x,y,StepNumber); { Взять координаты и номер шага} Inc(StepNumber); { Увеличить номер шага } PutAll(x,y,StepNumber,Found) { Занести в очередь все возможные ход} end; { Если среди них конечное поле, Found=true} writeln(StepNumber); { Вывод номера шага} end.