Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 23.05.2009, 20:40   #1
vikka
Пользователь
 
Регистрация: 18.12.2008
Сообщений: 19
По умолчанию задача в общем то рабочая. Но есть некоторые ошибки, посмотрите пожалуйста!

На плоскости расположено N точек. Имеется робот,который двигается следующим образом:стартуя с некоторой начальной точки и имея некоторое начальное напрвление, робот движется до первой встреченной на его пути точки,изменяя в ней свое направление на 90 градусов, т.е. поворачивая налево или направо. После этого он продолжает движение аналогично. Если робот достиг начальной точки, либо не может достичь новой точки (которую он еще на посещал), то он останавливается. Определить, может ли робот посетить все N точек, если:
1. определены начальные точка и направление робота.
2. определена начальная точка,а направление робота можно выбирать.
3. начальную точку и направление робота можно выбирать.
координаты точек-целые числа, угол измеряется в радианах относительно оси ОХ
vikka вне форума Ответить с цитированием
Старый 23.05.2009, 20:42   #2
vikka
Пользователь
 
Регистрация: 18.12.2008
Сообщений: 19
По умолчанию

t
Код:
ype

Ppoint=^Point;
Point=record
  n:integer;      //номер
  x:integer;     //координата x
  y:integer;     //координата y
  pright:Ppoint; //адрес правой
  ptop:Ppoint;   //адрес верхней
  pleft:Ppoint;  // адрес левой
  pbottom:Ppoint;//адрес нижней
  pnext:Ppoint;  //адрес следующей в списке
  isvalid:boolean;//точка связана с остальными
end;

var

 counter: integer; // количество точек
 angle: real; // угол поворота робота
 robotpoint: integer; // номер точки нахождения зщбота
 plist: Ppoint; // указатель на начало списка;
 fl : Text;
 newx, newy : integer;
 
 // добавление новой точки к списку
procedure addpoint(x,y:integer);
var
  pn   : Ppoint;
  pnextpoint: Ppoint;
                            // (нам придется влезять между ними)
begin
  counter := counter+1;
  new(pn);
  pn^.n := counter;
  pn^.x := x;
  pn^.y := y;
  pn^.pright := nil;
  pn^.ptop := nil;
  pn^.pleft := nil;
  pn^.pbottom := nil;
  pn^.pnext := nil;
  pn^.isvalid := false;

  if counter = 1 then plist := pn //Это первая точка
  else begin
  // сначала проход по списку и определение соседей
    pnextpoint := plist;
    while pnextpoint <> nil do begin

      if pnextpoint^.y = y then begin  // очередная точка на одной горизонтали
                                       // с новой точкой
      // справа
        if (pn^.pright = nil) and (pnextpoint^.x > x) then
          pn^.pright := pnextpoint else
        if (pnextpoint^.x > x) and (pnextpoint^.x < pn^.pright^.x) then
        // на данный момент, это ближе всех, запомним и идем дальше
          pn^.pright := pnextpoint;

      // слева
        if (pn^.pleft = nil) and (pnextpoint^.x < x) then
          pn^.pleft := pnextpoint else
        if (pnextpoint^.x < x) and (pnextpoint^.x > pn^.pleft^.x) then
        // на данный момент, это ближе всех, запомним и идем дальше
          pn^.pleft := pnextpoint;
      end;
      
      if pnextpoint^.x = x then begin  // очередная точка на одной вертикали
                                       // с новой точкой
      // сверху
        if (pn^.ptop = nil) and (pnextpoint^.y > y) then
          pn^.ptop := pnextpoint else
        if (pnextpoint^.y > y) and (pnextpoint^.y < pn^.ptop^.y) then
        // на данный момент, это ближе всех, запомним и идем дальше
          pn^.ptop := pnextpoint;

      // снизу
        if (pn^.pbottom = nil) and (pnextpoint^.y < y) then
          pn^.pbottom := pnextpoint else
        if (pnextpoint^.y < y) and (pnextpoint^.y > pn^.pbottom^.y) then
        // на данный момент, это ближе всех, запомним и идем дальше
          pn^.pbottom := pnextpoint;

      end;
      
      pnextpoint := pnextpoint^.pnext;
    end; // while pnextpoint <> nil

    // соседи определены, скажем им о новом соседе
    if pn^.pright <> nil then begin
      pn^.pright^.pleft := pn;
    end;
    if pn^.ptop <> nil then begin
      pn^.ptop^.pbottom := pn;
    end;
    if pn^.pleft <> nil then begin
      pn^.pleft^.pright := pn;
    end;
    if pn^.pbottom <> nil then begin
      pn^.pbottom^.ptop := pn;
    end;
    
    pn^.pnext := plist;
    plist := pn;

  end;
end;

(* проверка количества связей точки
результат
0 - связей нет, точка одиночка, в нее не попадещ никак, решений нет
1 - только одна связь, точка может быть началом илм концом маршрута,
    таких может быть только две, если больше - оешения нет
2 - "хорошая точка
*)
function testpoint(pn : Ppoint):integer;
var
 incount : integer; // количество входов
 isvalid : boolean; // выход есть.
begin
 isvalid := false;
 incount := 0;
 if pn^.pleft <> nil then begin
   incount := incount + 1;
   if (pn^.ptop <> nil) or (pn^.pbottom <> nil) then isvalid := true;
 end;
 if pn^.pright <> nil then begin
   incount := incount + 1;
   if (pn^.ptop <> nil) or (pn^.pbottom <> nil) then isvalid := true;
 end;
 if pn^.ptop <> nil then begin
   incount := incount + 1;
   if (pn^.pleft <> nil) or (pn^.pright <> nil) then isvalid := true;
 end;
 if pn^.pbottom <> nil then begin
   incount := incount + 1;
   if (pn^.pleft <> nil) or (pn^.pright <> nil) then isvalid := true;
 end;
 if incount = 0 then testpoint := 0;
 if incount = 1 then testpoint := 1;
 if isvalid then testpoint := 2;
end;

Последний раз редактировалось MaTBeu; 24.05.2009 в 18:14.
vikka вне форума Ответить с цитированием
Старый 23.05.2009, 20:43   #3
vikka
Пользователь
 
Регистрация: 18.12.2008
Сообщений: 19
По умолчанию

Код:
(* проверить направление робота
Результат истина, если повернут на точку, иначе ложно
*)
function testangle(pn : Ppoint):boolean;
begin
  testangle := false;
  if (pn^.pright <> nil) and (angle = 0)     then testangle := true;
  if (pn^.ptop   <> nil) and ( Round(angle*100) - Round(pi/2*100) = 0 )  then testangle := true;
  if (pn^.pleft  <> nil) and ( Round(angle*100) - Round(pi*100) = 0 )    then testangle := true;
  if (pn^.pbottom<> nil) and ( Round(angle*100) - Round(pi*3/2*100) = 0 )then testangle := true;

end;

(* проверить "связанность" всех точек *)
function testlinks:boolean;
var
  pnextpoint: Ppoint;
  moretest: boolean;
  isok : boolean;
begin
  moretest := true;
  plist^.isvalid := true;
  if plist^.pright <> nil then plist^.pright^.isvalid := true
  else if plist^.ptop <> nil then plist^.ptop^.isvalid := true
  else if plist^.pleft <> nil then plist^.pleft^.isvalid := true
  else if plist^.pbottom <> nil then plist^.pbottom^.isvalid := true;
  while moretest do begin
    moretest := false;
    pnextpoint := plist;
    while pnextpoint <> nil do begin
//      validnext := validlist;
      if pnextpoint^.isvalid then begin
          if pnextpoint^.pright <> nil then begin
            if pnextpoint^.pright^.isvalid then begin
              if pnextpoint^.ptop <> nil then
              if not pnextpoint^.ptop^.isvalid then begin
                pnextpoint^.ptop^.isvalid := true;
                moretest := true;
              end;
              if pnextpoint^.pbottom <> nil then
              if not pnextpoint^.pbottom^.isvalid then begin
                pnextpoint^.pbottom^.isvalid := true;
                moretest := true;
              end;
            end;
          end;

          if pnextpoint^.pleft <> nil then begin
            if pnextpoint^.pleft^.isvalid then begin
              if pnextpoint^.ptop <> nil then
              if not pnextpoint^.ptop^.isvalid then begin
                pnextpoint^.ptop^.isvalid := true;
                moretest := true;
              end;
              if pnextpoint^.pbottom <> nil then
              if not pnextpoint^.pbottom^.isvalid then begin
                pnextpoint^.pbottom^.isvalid := true;
                moretest := true;
              end;
            end;
          end;

          if pnextpoint^.ptop <> nil then begin
            if pnextpoint^.ptop^.isvalid then begin
              if pnextpoint^.pleft <> nil then
              if not pnextpoint^.pleft^.isvalid then begin
                pnextpoint^.pleft^.isvalid := true;
                moretest := true;
              end;
              if pnextpoint^.pright <> nil then
              if not pnextpoint^.pright^.isvalid then begin
                pnextpoint^.pright^.isvalid := true;
                moretest := true;
              end;
            end;
          end;

          if pnextpoint^.pbottom <> nil then begin
            if pnextpoint^.pbottom^.isvalid then begin
              if pnextpoint^.pleft <> nil then
              if not pnextpoint^.pleft^.isvalid then begin
                pnextpoint^.pleft^.isvalid := true;
                moretest := true;
              end;
              if pnextpoint^.pright <> nil then
              if not pnextpoint^.pright^.isvalid then begin
                pnextpoint^.pright^.isvalid := true;
                moretest := true;
              end;
            end;
          end;
        end;
      pnextpoint:= pnextpoint^.pnext;
    end; // while pnextpoint <> nil
  end;
  
  isok := true;
  pnextpoint := plist;
  while pnextpoint <> nil do begin
    if not pnextpoint^.isvalid then isok := false;
    pnextpoint:= pnextpoint^.pnext;
  end; // while pnextpoint <> nil
  testlinks := isok;
end;

(* решение задачи *)
procedure testresult;
var
  pnextpoint: Ppoint;
  i : integer;
  count : integer;
  p1,p2 :  Ppoint;
begin

    if not testlinks() then begin
        writeln('Решений нет');
        Halt;
    end;
    count := 0;
    pnextpoint := plist;
    while pnextpoint <> nil do begin
      i := testpoint(pnextpoint);
      if i = 0 then // подвисшая без соседей точка, сюда не попадешь
      begin
        writeln('Решений нет');
        Halt;
      end;
      if i = 1 then // начало/конец маршрута
      begin
        count := count +1;
        if count > 2 then begin
          writeln('Решений нет');
          Halt;
        end;
        if count = 1 then p1 := pnextpoint else p2 := pnextpoint;
      end;
      pnextpoint := pnextpoint^.pnext;
    end; // while pnextpoint <> nil
    writeln;
    write('Решение 3 существует, ');

Последний раз редактировалось MaTBeu; 24.05.2009 в 18:14.
vikka вне форума Ответить с цитированием
Старый 23.05.2009, 20:43   #4
vikka
Пользователь
 
Регистрация: 18.12.2008
Сообщений: 19
По умолчанию

Код:
// ищем точку расположения робота
    pnextpoint := plist;
    while pnextpoint <> nil do begin
      if robotpoint = pnextpoint^.n then begin
        if count = 0 then begin
          write(' решение 2 существует,');
          if testangle(pnextpoint) then writeln(' решение 1 существует')
                                   else writeln(' решение 1 не существует');
            halt;
        end else if count < 3 then begin
          if (pnextpoint = p1) or (pnextpoint =p2) then begin
            write(' решение 2 существует,');
            if testangle(pnextpoint) then writeln(' решение 1 существует')
                                     else writeln(' решение 1 не существует');

          end else writeln(' решение 2 не существует, решение 1 не существует');
          halt;
        end;
      end;
      pnextpoint := pnextpoint^.pnext;
    end; // while pnextpoint <> nil

    writeln(' решение 2 не существует, решение 1 не существует');
end;
 
begin
counter := 0;

Assign(fl,'c:\input.dat');
Reset(fl);
Readln(fl, robotpoint, angle);
while not Eof(fl) do begin
  Readln(fl, newx, newy);
  Writeln('read ',newx,',', newy);
  if newx+newy <> 0 then
    addpoint(newx, newy);
end;
Close(fl);

testresult();

end.

Последний раз редактировалось MaTBeu; 24.05.2009 в 18:14.
vikka вне форума Ответить с цитированием
Старый 24.05.2009, 18:05   #5
vikka
Пользователь
 
Регистрация: 18.12.2008
Сообщений: 19
По умолчанию

если в сохраненном файле изменить некоторые цифры,то не всегда выдает правильный ответ.что делать???=(
vikka вне форума Ответить с цитированием
Старый 24.05.2009, 18:15   #6
MaTBeu
Eclipse Foundation
Старожил
 
Аватар для MaTBeu
 
Регистрация: 19.09.2007
Сообщений: 2,604
По умолчанию

Вы вообще нормальный человек? Кто будет рыться в 2000 строках кода чтобы найти вам ошибку? Сделайте отладку.
MaTBeu вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
ПОСМОТРИТЕ, ПОЖАЛУЙСТА, ПРОГРАММЫ НА ЯЗЫКЕ ПАСКАЛЬ!! СРОЧНО!! ЕСТЬ НАРАБОТКИ) НАСТЯ 18:) Помощь студентам 33 10.05.2009 15:23
В Turbo C++ Есть рабочая игрушка, но если долго играть начинает искаженно рисовать графику Subaru Помощь студентам 2 30.01.2009 09:21
Посмотрите на мой АЖАКС не найду ошибки mogul82 JavaScript, Ajax 3 31.10.2008 22:13
Системы счисления помогите решить и посмотрите ошибки vdv08 Паскаль, Turbo Pascal, PascalABC.NET 1 13.05.2008 15:58
Ошибки компиляции. У кого есть =*=|/|MM0PT@/\=*= Паскаль, Turbo Pascal, PascalABC.NET 4 02.04.2007 06:10