![]() |
|
|
Регистрация Восстановить пароль |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
![]() |
|
|
Опции темы | Поиск в этой теме |
![]() |
#21 | ||
Санитар
Старожил
Регистрация: 04.10.2008
Сообщений: 2,577
|
![]() Цитата:
Цитата:
Код:
а лучше я пока что не придумал, я думаю нужно больше информации о списке, может быть он отсортированный? - тогда задача тривиальна и реально решается за линейное время. Или может быть известно количество элементов в списке ? - тогда решается тоже за линейное.. |
||
![]() |
![]() |
![]() |
#22 |
Тот ещё
Старожил
Регистрация: 14.11.2007
Сообщений: 2,242
|
![]() Код:
|
![]() |
![]() |
![]() |
#23 |
Пользователь
Регистрация: 23.01.2013
Сообщений: 10
|
![]() |
![]() |
![]() |
![]() |
#24 |
Тот ещё
Старожил
Регистрация: 14.11.2007
Сообщений: 2,242
|
![]()
Хотелось бы еще отметить, что приведенные мной функции MyListCount и MyListClear работают только для кольцевого не пустого списка.
Вот подкорректировал их для более общего случая Код:
|
![]() |
![]() |
![]() |
#25 |
Санитар
Старожил
Регистрация: 04.10.2008
Сообщений: 2,577
|
![]()
Sibedir
угу, прикольно ) но рекурсию можно не исопльзовать (стек особо не тиранить), но также обнулять указатели next всех пройденных элементов. При этом список сломается и память утечет, а чтобы все сохранить можно указаетли на все пройденные элементы засунуть в еще один список - тогда и паять можно корректно освободить и исходный список со всеми его петлями восстановить. На плюсиках как-то так: Код:
![]() Последний раз редактировалось rrrFer; 24.01.2013 в 10:52. |
![]() |
![]() |
![]() |
#26 |
Тот ещё
Старожил
Регистрация: 14.11.2007
Сообщений: 2,242
|
![]() |
![]() |
![]() |
![]() |
#27 |
Great Code Monkey
Форумчанин
Регистрация: 09.08.2007
Сообщений: 533
|
![]()
Решал эту задачу на собеседовании)
Пускаем от начала списка два указателя - один из них движется со скоростью 1, другой со скоростью 2. В какой-то момент быстрый догонит медленный и они встретятся. Теперь пускаем один указатель от начала списка, а другой от точки встречи - оба со скоростью 1. В общем там из математики следует, что они встретятся точно в начале цикла. Требования по памяти и асимптотике при этом удовлетворяются. Дальше элементарщина) |
![]() |
![]() |
![]() |
#28 |
Тот ещё
Старожил
Регистрация: 14.11.2007
Сообщений: 2,242
|
![]()
Круто, still_alive. Так и думал, что задача решается по средствам математики, но ни чего дельного в голову не пришло, а искать не хотелось.
Добавлено ----------------------------------------------------------------------- Кстати, а как быть с Хотя признаю, можно извратиться и запихнуть это в рекурсию, а потом еще на ASM'е извратиться и избавиться от записи (уже не нужных) значений в стек, а использовать только регистры (ну может пару значений в стеке). Последний раз редактировалось Sibedir; 24.01.2013 в 13:35. |
![]() |
![]() |
![]() |
#29 |
Санитар
Старожил
Регистрация: 04.10.2008
Сообщений: 2,577
|
![]()
still_alive
это очень круто и работает вроде-бы, а доказать у меня не получилось... Я решил сначала вычислить через сколько клеток 2 указателя (с разными скоростями) встретятся... получилось равенство, которое я не знаю как решать ) Я разделил список на 2 отрезка - линейный и циклический (А и В). и пусть p1 - медленный, р2 - быстрый указатели. ясно что раньше чем через А шагов указатели встретица не могут. через А шагов между ними будет А mod В элементов списка. а встретятся они через x шагов, которое нужно определить из равенства: x mod B = (2*x + (A mod B)) mod B и при этом решить надо в целых числах... подскажи как ты это сделал? или намекни правильный запрос гуглу, пожалсто ) |
![]() |
![]() |
![]() |
#30 |
Тот ещё
Старожил
Регистрация: 14.11.2007
Сообщений: 2,242
|
![]()
Есть 2 путевых обходчика и наш стек. Стек состоит из хвоста и цикла.
Пусть: А - длина хвоста B - длина цикла До первой встречи обходчики пройдут (A+x) и (A+nB+x) соответственно. Из условия их скорости ясно, что: 2(A+x) = (A+nB+x) далее 2A+2x = A+nB+x 2A-А = nB+x-2x A = nB-x а выражение (nB-x) есть ничто иное, как расстояние, которое нужно пройти второму со скоростью 1 чтобы завершить цикл, ведь x от начала цикла он уже прошел (x+(nB-x) = nB). Следовательно, если первый начнет сначала, а второй продолжит, то через A шагов они оба окажутся на первом элементе цикла. вычислить через сколько клеток 2 указателя встретятся ~ найти A+x 1. A+x = nB 2. n = (A+x)/B 3. можно легко доказать, что при любом положении обходчиков на цикле второй догонит первого менее чем за В (при В>1) ходов (не сможет его перескочить (каждый ход расстояние м/у ними уменьшается на 1 и в итоге станет 0 (палюбому)), перескок возможен только при сторости второго >2). 4. т.к. x<B => n = (A div B)+1 5. A+x = B*((A div B)+1) Последний раз редактировалось Sibedir; 25.01.2013 в 07:51. |
![]() |
![]() |
![]() |
|
![]() |
||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Связанный список | Лжец | Общие вопросы C/C++ | 2 | 12.12.2011 23:42 |
Связанный список на СИ | maryan.vetrov | Общие вопросы C/C++ | 6 | 18.10.2010 08:49 |
Связанный список (Linked list). | lnter | Помощь студентам | 0 | 12.04.2010 17:58 |
База данных. Связанный список. | 4uJIaBekTonop | C/C++ Базы данных | 3 | 29.12.2009 10:42 |