проблема
Скажем, у вас есть N стеков с именами от S 1 до S N , где каждый S k (от k = 1 до N) содержит N копий числа k.
Например, когда N = 3, стеки выглядят так:
1 2 3 <- top of stack
1 2 3
1 2 3 <- bottom of stack
=======
1 2 3 <- stack index
Здесь есть 3 стека, проиндексированных как 1, 2 и 3, и каждый содержит N экземпляров своего собственного индекса.
Цель состоит в том, чтобы переставить N стеков так, чтобы каждое из них идентично содержало числа от 1 до N в порядке сверху вниз.
например, для N = 3 цель состоит в том, чтобы переставить стеки в:
1 1 1
2 2 2
3 3 3
=======
1 2 3
Единственное действие, которое вы можете выполнить со стеками, - это взять верхний номер из одного из стеков (выталкивание), а затем немедленно поместить его поверх другого стека (толкание) . Это зависит от следующих условий:
Число может быть помещено в стек только в том случае, если оно меньше или равно верхнему числу в этом стеке.
например,
1
может быть выдвинут на стек с1
,2
или3
в верхней части, но2
может быть выдвинут только на стек с2
или3
(или выше) в верхней части.Это приводит к тому, что стеки всегда монотонно увеличиваются сверху вниз.
Любой непустой стек может быть извлечен, и, если предыдущий маркер удовлетворен, любой стек может быть передан.
Любое число может быть помещено в пустой стек.
Стеки не имеют ограничения по максимальной высоте.
Стеки не могут быть созданы или уничтожены, их всегда N.
Эта задача состоит в том, чтобы решить, какие щелчки и толчки нужно сделать, чтобы завершить обмен стека, причем не обязательно за наименьшее количество ходов, но безошибочно.
(Практика с колодой карт - хороший способ почувствовать проблему.)
Вызов
Напишите программу или функцию, которая принимает положительное целое число N, гарантированно равное 3 или выше. Выведите или верните строку, которая обозначает все всплывающие действия, необходимые для перестановки стеков из исходного состояния:
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
=============
1 2 3 4 5
(Случай N = 5)
До конечного состояния:
1 1 1 1 1
2 2 2 2 2
3 3 3 3 3
4 4 4 4 4
5 5 5 5 5
=============
1 2 3 4 5
Каждая строка в вашем выводе должна содержать два числа, разделенных пробелом. Первое число - это индекс стека для извлечения, а второе число - это индекс стека, к которому нужно выдвинуть. Выполнение действий всех линий по порядку должно правильно расставлять стеки, не нарушая никаких правил.
Например, вот потенциальный допустимый выход для случая N = 3:
1 2 [move the top number on stack 1 to the top of stack 2]
1 2 [repeat]
1 2 [repeat]
3 1 [move the top number on stack 3 to the top of stack 1]
2 3 [etc.]
2 3
2 3
2 1
2 1
2 1
3 1
3 1
3 1
3 2
1 2
1 2
1 2
1 3
2 3
2 3
2 3
1 2
3 2
3 1
Заметки
Ваш вывод не должен быть оптимальным , только правильным. т.е. вам не нужно минимизировать количество всплывающих окон и толчков.
- Так что было бы хорошо, если бы, скажем, какой-то шаг был неоднократно сделан и немедленно изменен.
- Попадание в один и тот же стек за один ход, например
2 2
, также разрешено (хотя, конечно, бессмысленно).
Ваш вывод делает потребность быть детерминированным и конечным.
Помните, что стеки имеют индексирование на основе 1. Индексирование на основе 0 не допускается.
N больше 9, конечно, должно работать так же хорошо, как однозначное число N.
При желании вы можете использовать любые два различных нецифровых печатаемых символа ASCII вместо пробелов и символов новой строки. Конечный символ новой строки (или заменитель новой строки) в выводе - это нормально.
счет
Самый короткий код в байтах побеждает. Ответ Tiebreaker выше.
Бесполезные очки брауни, если вы можете показать, что ваш алгоритм оптимален.
источник
-._(._.)_.-
N=3
оптимального?Ответы:
Pyth
9694 байтаПопробуй здесь
Как это работает?
Это объяснение будет использовать N = 5.
Часть 1. Создание нижнего слоя в каждом стеке
Причина, по которой для этого нужен отдельный фрагмент кода, заключается в том, что необходимо использовать каждый стек: первым 4 нужно поместить 5 под ними, а последний стек должен предоставить 5. Это означает, что мы не можем просто переместить все четверки куда-либо, поставить туда 5 и сдвинуть четверки назад.
Визуализация: (круглые скобки означают, что будет перемещено)
Вместо этого, чтобы сделать этот первый обмен, мы сначала переместим все 1 во второй стек, переместим 5 в первый стек (который теперь пуст), переместим 1 в третий стек, переместим 2 в первый стек, переместите 1 обратно в первый стек и, наконец, 5 во второй стек.
Теперь, когда у нас есть свободное пространство для перемещения стеков (стек 2, который содержит только 5, который помещен в правильное место), мы можем переместить все 3 с в стек 2 и поместить 5 в стек 3. Затем мы можем повторить то же самое для стека 4, и теперь мы получаем все 5 в нужном месте! И еще одна вещь: мы переместим все 1 в стек 5, чтобы получить хорошую настройку для следующего обмена стека.
Часть 2: Делай все остальное :)
Теперь это намного проще, потому что теперь у нас всегда будет свободный стек для перемещения других чисел, в которые нам нужно перетасовываться. Итак, сначала мы выясним, где находится 4. Немного изучения покажет, что он всегда будет на 1 выше, чем с начала, или на 2 выше последнего стека. Теперь мы просто продолжаем идти вниз по стопкам, помещая 4 в стек, если он свободен, или перемещая другие числа на 1 стопку, если это не так. Теперь у нас есть все четверки на месте.
Теперь мы понимаем, что 3s на 2 стека выше, где 4s, где. Это означает, что мы можем сделать то же самое, что и с 4-мя! И, как оказалось, мы можем продолжать делать это до тех пор, пока не перевернем индекс стека на другую сторону.
И так, мы можем продолжать делать это, пока мы не обменяем все стеки.
Объяснение кода:
Прежде всего: (важные) предопределенные переменные.
Есть 2 лямбда-определения.
Обмен стеком: часть 1
Обмен стеком: часть 2
Я уже знаю, что я не получаю очки брауни, потому что я вижу много более эффективных и более сложных методов :(
источник