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

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

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

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


Новичок
*

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

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


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

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

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

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

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


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

 





- Текстовая версия 24.04.2024 1:03
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name