IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

> Удав, Задача на координаты и направление
1qsd
сообщение 26.03.2007 14:59
Сообщение #1


Новичок
*

Группа: Пользователи
Сообщений: 11
Пол: Мужской
Реальное имя: Kost

Репутация: -  0  +


Помогите решить вот эту несложную задачу. Преподаватель говорит, что решать её нужно как то через матрицы.

Удав расположен в виде нескольких линий, из которых каждая следущая перпендикулярна предыдущей. Направление каждой линии и её протяженность задаются буквами "L" , "R" и числом.

Например 25L15R5 ("25" - длина линии = 25, "L" - поворачивает на 90 градусов влево, "15" - длина линии = 15 , "R" - поворачивает на 90 градусов вправо , "5" - длина линии = 5).

Определить, пересечет ли он себя.

Сообщение отредактировано: 1qsd - 26.03.2007 15:17
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов
Lapp
сообщение 27.03.2007 7:43
Сообщение #2


Уникум
*******

Группа: Модераторы
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


Я тоже не придумал, как тут использовать матрицы, кроме заполнения поля единицами на месте его тела, но этот способ сильно ограничивает размеры удава и крайне неэффективен по использованию памяти. Была у меня мыслишка сжимать эту "матрицу" на лету, но я все же решил пойти другим путем - традиционным, геометрическим.

Учитывая структуру входной строки, звенья удава все время чередуются: горизонтальное - вертикальное, и снова. Мой алгоритм прост:
1. иду по удаву с начала и до конца
2. координаты текущего звена сравниваю:
- если четное, с нечетными;
- если нечетное, с четными
3. сравнение заключается в оценке на отрицательность или равенство нулю произведения:
(Xi - Xj)*(Xi-1 - Xj) - это для нечетных,
(Yi - Yj)*(Yi-1 - Yj) - это для четных.
Здесь Xi, Xi-1 - координаты текущего звена, а Xj - координата звена, с которым сравниваем (то же самое для Y). Замечу, что я считаю первое звено расположенное началом в т. 0,0 , а конец - в положительном направлении по оси Х. Сиситема координат обычная математическая (х - вправо, у - вверх).

Чуть ли не больше половины занимает парсинг входной строки (простейший) с заполнением массивов координат X и Y. Он делается с помощью поворотов вектора направлений (Dir). Для этого использую матрицу поворотов (аналогично как в теме Лабиринт , но без выделения в отдельную процедуру).

Программа читает из файла boa.dat, в нем не должно быть никаких других символов, кроме L, R и цифр (даже концов строк!). Находит (простите - должна находить! smile.gif) все пересечения и сообщает номера пересекающихся звеньев. Если ничего не пересекается - выходит молча smile.gif.

Я проверял на такой вот строчке:
10R5L6L3L12R5
В ней два пересечения: 2х5, 1х6

Вот сам код:
{ Searching self-crossings of a Boa }
{ by Lapp }
const
m=100;

var
x,y:array[0..m]of integer;
Dir:record
x,y:integer
end;
i,j,n,e,l,z:integer;
Cross:boolean;
c:char;
s:string;
f:file of char;

begin
{ Data input }
x[0]:=0; y[0]:=0;
Dir.x:=1; Dir.y:=0;
Assign(f,'boa.dat');
Reset(f);
n:=0;
while not EoF(f) do begin
Read(f,c);
c:=UpCase©;
if (c in ['L','R'])or EoF(f) then begin
Inc(n);
if EoF(f) then s:=s+c;
Val(s,l,e);
x[n]:=x[n-1]+Dir.x*l;
y[n]:=y[n-1]+Dir.y*l;
s:='';
with Dir do case c of
'L':begin z:=x; x:=-y; y:=z end;
'R':begin z:=x; x:=y; y:=-z end;
end
end
else s:=s+c
end;
{ Start working}
for i:=2 to n do begin
Cross:=false;
j:=i mod 2;
while not Cross and (j<i-2) do begin
if Odd(i) then
Cross:=Odd(j) and ((x[i]-x[j])*(x[i-1]-x[j])<=0)
else
Cross:=not Odd(j) and ((y[i]-y[j])*(y[i-1]-y[j])<=0);
if Cross then begin
WriteLn('Bonds #',j+1,' and #',i,' are crossed over');
Cross:=false
end;
Inc(j,2)
end
end
end.


Добавлено через 8 мин.
Да, еще забыл ответить Michael_Rybak'у..
Я не склонен тут выделять касания, поскольку все происходит на дискретной сетке. Я понимаю, что ты хочешь сказать (это, видимо, относится к топологии), но не думаю, что условие задачи трактовалось так. Любое совпадение точек, принадлежащим звеньям (кроме сочленений соседних звеньев) считаю пересечением.
Но я не говорю, что топологический аспект не представляет интереса! smile.gif Вполне даже может быть..


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

Сообщений в этой теме
1qsd   Удав   26.03.2007 14:59
мисс_граффити   С матрицами... Единственная идея: берем матрицу из...   26.03.2007 17:04
1qsd   1) можно и не через матрицы 2) можно пользоваться ...   26.03.2007 18:03
мисс_граффити   Идея такая: разбиваем удавчика на отрезки, которые...   26.03.2007 19:15
1qsd   давайте по порядку 1) как записывать в массив: сам...   26.03.2007 19:51
мисс_граффити   1) мне кажется, тут подойдет запись с тремя полями...   26.03.2007 20:09
1qsd   А вы можете код с клеточками (во втором сообщении ...   26.03.2007 20:37
мисс_граффити   а сам не хочешь попробовать хотя бы?   26.03.2007 21:24
Michael_Rybak   И уточни еще, что если он не пересекает себя, но к...   26.03.2007 22:15
Lapp   Я тоже не придумал, как тут использовать матрицы, ...   27.03.2007 7:43
Lapp   Идея такая: разбиваем удавчика на отрезки, которы...   27.03.2007 11:52
Michael_Rybak   В таком случае горизонтальные нельзя проверять т...   27.03.2007 13:43
Malice   В таком случае горизонтальные нельзя проверять то...   27.03.2007 14:54
Michael_Rybak   10L10L10R10R10R30   27.03.2007 17:02
Гость   О чем я и говорил. Пересекает еще и смежные отрезк...   27.03.2007 18:23
Malice   Эт я был.. Я же имел ввиду случай типа:   27.03.2007 18:29
Michael_Rybak   Он не пересекает смежные отрезки. Я ведь специальн...   27.03.2007 21:06
Malice   Гы :) В таком случает надо определьтся - включает ...   27.03.2007 21:35
Michael_Rybak   У меня не получался нигде квадрат 11х11. Получало...   27.03.2007 22:53
Lapp   Критику принял. Думаю..   28.03.2007 0:06
Lapp   Коллеги, я не вполне все же вас понял.. Michael_Ry...   28.03.2007 1:30
Lapp   2 Malice: Случай с подходом к хвосту сзади лечится...   28.03.2007 2:23
Lapp   Неужели Michael_Rybak все же прав (сам того не зн...   28.03.2007 5:27
Lapp   2 Lapp: (а с кем еще и поговорить-то ночью.. :)) В...   28.03.2007 6:26
1qsd   Если удав выглядит как спираль, например так 1R2R3...   28.03.2007 8:33
Lapp   например так 1R2R3R4R5R6 ... программма не работа...   28.03.2007 10:19
Lapp   По ходу дела, посмотрев на все сложности, возникши...   28.03.2007 12:29
Malice   Теперь я думаю, как говорится, тема раскрыта :) Я ...   28.03.2007 18:18
Michael_Rybak   Я считаю, что нужно строго определить самопересече...   28.03.2007 18:23
Lapp   Мужики, не драматизируйте ситуацию. Не забывайте ...   29.03.2007 1:02


 Ответить  Открыть новую тему 
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 



- Текстовая версия 18.07.2025 9:12
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"