Показать сообщение отдельно
Старый 22.03.2012, 18:10   #2
shybovycha
ПроЭктировщик
 
Аватар для shybovycha
 
Регистрация: 27.05.2007
Сообщений: 110
Написано 40 полезных сообщений
(для 33 пользователей)
Ответ: Лабиринты.Графы.Пути

Волновой алгоритм. Не уверен, как сделать что-то вроде std::vector / std::queue в паскале, но допустим есть у вас класс, позволяющий добавлять в конец списка элемент и "выталкивать" элемент с начала списка. И допустим есть у вас класс "точка" - ради сохранения координат клетки (строка, столбец). Пускай в матрице M пустая клетка имеет значение 0, а не пустая - свой номер.

Алгоритм следующий:

// прошу прощения за Сишные выражения в некоторых местах =)
stack := [];

for (y := 0 to rows) do
begin
  for (x := 0 to columns) do
  begin
    if (M[y][x] != 0) then //  клетка не пуста
    begin
      stack.push(Point(x, y));
      break;
    end;

    // нашли первую не пустую клетку
    if (stack.size() > 0) then
      break;
end;

// для связи предыдущей и текущей клеток
Point previous := null;

while (stack.size() > 0) do
begin
  Point p := stack.pop(); // достаем из стека координаты первой клетки, от которой будем "плясать"

  // ищем вокруг "пляшущей" клетки все, от которых можем плясать
  if (M[p.y + 1][p.x] != 0) then stack.push(Point(p.x, p.y + 1);
  if (M[p.y - 1][p.x] != 0) then stack.push(Point(p.x, p.y - 1);
  if (M[p.y][p.x + 1] != 0) then stack.push(Point(p.x + 1, p.y);
  if (M[p.y][p.x - 1] != 0) then stack.push(Point(p.x - 1, p.y);

  // случай с перой найденной клеткой
  if (previous != null) then
  begin
    File.WriteLine(M[previous.y][previous.x], ' ', M[p.y][p.x]);
  end;

  previous := p;
end;
(Offline)
 
Ответить с цитированием